OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 return false; | 1805 return false; |
1806 } | 1806 } |
1807 } | 1807 } |
1808 return true; | 1808 return true; |
1809 } | 1809 } |
1810 | 1810 |
1811 | 1811 |
1812 MaybeObject* JSObject::AddFastProperty(Name* name, | 1812 MaybeObject* JSObject::AddFastProperty(Name* name, |
1813 Object* value, | 1813 Object* value, |
1814 PropertyAttributes attributes, | 1814 PropertyAttributes attributes, |
1815 StoreFromKeyed store_mode) { | 1815 StoreFromKeyed store_mode, |
| 1816 ValueType value_type) { |
1816 ASSERT(!IsJSGlobalProxy()); | 1817 ASSERT(!IsJSGlobalProxy()); |
1817 ASSERT(DescriptorArray::kNotFound == | 1818 ASSERT(DescriptorArray::kNotFound == |
1818 map()->instance_descriptors()->Search( | 1819 map()->instance_descriptors()->Search( |
1819 name, map()->NumberOfOwnDescriptors())); | 1820 name, map()->NumberOfOwnDescriptors())); |
1820 | 1821 |
1821 // Normalize the object if the name is an actual name (not the | 1822 // Normalize the object if the name is an actual name (not the |
1822 // hidden strings) and is not a real identifier. | 1823 // hidden strings) and is not a real identifier. |
1823 // Normalize the object if it will have too many fast properties. | 1824 // Normalize the object if it will have too many fast properties. |
1824 Isolate* isolate = GetHeap()->isolate(); | 1825 Isolate* isolate = GetHeap()->isolate(); |
1825 if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name) | 1826 if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name) |
1826 && name != isolate->heap()->hidden_string()) || | 1827 && name != isolate->heap()->hidden_string()) || |
1827 (map()->unused_property_fields() == 0 && | 1828 (map()->unused_property_fields() == 0 && |
1828 TooManyFastProperties(properties()->length(), store_mode))) { | 1829 TooManyFastProperties(properties()->length(), store_mode))) { |
1829 Object* obj; | 1830 Object* obj; |
1830 MaybeObject* maybe_obj = | 1831 MaybeObject* maybe_obj = |
1831 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1832 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1832 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1833 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1833 | 1834 |
1834 return AddSlowProperty(name, value, attributes); | 1835 return AddSlowProperty(name, value, attributes); |
1835 } | 1836 } |
1836 | 1837 |
1837 // Compute the new index for new field. | 1838 // Compute the new index for new field. |
1838 int index = map()->NextFreePropertyIndex(); | 1839 int index = map()->NextFreePropertyIndex(); |
1839 | 1840 |
1840 // Allocate new instance descriptors with (name, index) added | 1841 // Allocate new instance descriptors with (name, index) added |
1841 Representation representation = IsJSContextExtensionObject() | 1842 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
1842 ? Representation::Tagged() : value->OptimalRepresentation(); | 1843 Representation representation = value->OptimalRepresentation(value_type); |
1843 | 1844 |
1844 FieldDescriptor new_field(name, index, attributes, representation); | 1845 FieldDescriptor new_field(name, index, attributes, representation); |
1845 | 1846 |
1846 ASSERT(index < map()->inobject_properties() || | 1847 ASSERT(index < map()->inobject_properties() || |
1847 (index - map()->inobject_properties()) < properties()->length() || | 1848 (index - map()->inobject_properties()) < properties()->length() || |
1848 map()->unused_property_fields() == 0); | 1849 map()->unused_property_fields() == 0); |
1849 | 1850 |
1850 FixedArray* values = NULL; | 1851 FixedArray* values = NULL; |
1851 | 1852 |
1852 // TODO(verwaest): Merge with AddFastPropertyUsingMap. | 1853 // TODO(verwaest): Merge with AddFastPropertyUsingMap. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 if (dict != result) set_properties(NameDictionary::cast(result)); | 1950 if (dict != result) set_properties(NameDictionary::cast(result)); |
1950 return value; | 1951 return value; |
1951 } | 1952 } |
1952 | 1953 |
1953 | 1954 |
1954 MaybeObject* JSObject::AddProperty(Name* name, | 1955 MaybeObject* JSObject::AddProperty(Name* name, |
1955 Object* value, | 1956 Object* value, |
1956 PropertyAttributes attributes, | 1957 PropertyAttributes attributes, |
1957 StrictModeFlag strict_mode, | 1958 StrictModeFlag strict_mode, |
1958 JSReceiver::StoreFromKeyed store_mode, | 1959 JSReceiver::StoreFromKeyed store_mode, |
1959 ExtensibilityCheck extensibility_check) { | 1960 ExtensibilityCheck extensibility_check, |
| 1961 ValueType value_type) { |
1960 ASSERT(!IsJSGlobalProxy()); | 1962 ASSERT(!IsJSGlobalProxy()); |
1961 Map* map_of_this = map(); | 1963 Map* map_of_this = map(); |
1962 Heap* heap = GetHeap(); | 1964 Heap* heap = GetHeap(); |
1963 Isolate* isolate = heap->isolate(); | 1965 Isolate* isolate = heap->isolate(); |
1964 MaybeObject* result; | 1966 MaybeObject* result; |
1965 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 1967 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
1966 !map_of_this->is_extensible()) { | 1968 !map_of_this->is_extensible()) { |
1967 if (strict_mode == kNonStrictMode) { | 1969 if (strict_mode == kNonStrictMode) { |
1968 return value; | 1970 return value; |
1969 } else { | 1971 } else { |
1970 Handle<Object> args[1] = {Handle<Name>(name)}; | 1972 Handle<Object> args[1] = {Handle<Name>(name)}; |
1971 return isolate->Throw( | 1973 return isolate->Throw( |
1972 *isolate->factory()->NewTypeError("object_not_extensible", | 1974 *isolate->factory()->NewTypeError("object_not_extensible", |
1973 HandleVector(args, 1))); | 1975 HandleVector(args, 1))); |
1974 } | 1976 } |
1975 } | 1977 } |
1976 | 1978 |
1977 if (HasFastProperties()) { | 1979 if (HasFastProperties()) { |
1978 // Ensure the descriptor array does not get too big. | 1980 // Ensure the descriptor array does not get too big. |
1979 if (map_of_this->NumberOfOwnDescriptors() < | 1981 if (map_of_this->NumberOfOwnDescriptors() < |
1980 DescriptorArray::kMaxNumberOfDescriptors) { | 1982 DescriptorArray::kMaxNumberOfDescriptors) { |
1981 if (value->IsJSFunction()) { | 1983 if (value->IsJSFunction()) { |
1982 result = AddConstantFunctionProperty(name, | 1984 result = AddConstantFunctionProperty(name, |
1983 JSFunction::cast(value), | 1985 JSFunction::cast(value), |
1984 attributes); | 1986 attributes); |
1985 } else { | 1987 } else { |
1986 result = AddFastProperty(name, value, attributes, store_mode); | 1988 result = AddFastProperty( |
| 1989 name, value, attributes, store_mode, value_type); |
1987 } | 1990 } |
1988 } else { | 1991 } else { |
1989 // Normalize the object to prevent very large instance descriptors. | 1992 // Normalize the object to prevent very large instance descriptors. |
1990 // This eliminates unwanted N^2 allocation and lookup behavior. | 1993 // This eliminates unwanted N^2 allocation and lookup behavior. |
1991 Object* obj; | 1994 Object* obj; |
1992 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1995 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1993 if (!maybe->To(&obj)) return maybe; | 1996 if (!maybe->To(&obj)) return maybe; |
1994 result = AddSlowProperty(name, value, attributes); | 1997 result = AddSlowProperty(name, value, attributes); |
1995 } | 1998 } |
1996 } else { | 1999 } else { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 ASSERT(target_number_of_fields >= number_of_fields); | 2263 ASSERT(target_number_of_fields >= number_of_fields); |
2261 if (target_number_of_fields != number_of_fields) return true; | 2264 if (target_number_of_fields != number_of_fields) return true; |
2262 | 2265 |
2263 if (FLAG_track_double_fields) { | 2266 if (FLAG_track_double_fields) { |
2264 // If smi descriptors were replaced by double descriptors, rewrite. | 2267 // If smi descriptors were replaced by double descriptors, rewrite. |
2265 DescriptorArray* old_desc = instance_descriptors(); | 2268 DescriptorArray* old_desc = instance_descriptors(); |
2266 DescriptorArray* new_desc = target->instance_descriptors(); | 2269 DescriptorArray* new_desc = target->instance_descriptors(); |
2267 int limit = NumberOfOwnDescriptors(); | 2270 int limit = NumberOfOwnDescriptors(); |
2268 for (int i = 0; i < limit; i++) { | 2271 for (int i = 0; i < limit; i++) { |
2269 if (new_desc->GetDetails(i).representation().IsDouble() && | 2272 if (new_desc->GetDetails(i).representation().IsDouble() && |
2270 old_desc->GetDetails(i).representation().IsSmi()) { | 2273 !old_desc->GetDetails(i).representation().IsDouble()) { |
2271 return true; | 2274 return true; |
2272 } | 2275 } |
2273 } | 2276 } |
2274 } | 2277 } |
2275 | 2278 |
2276 // If no fields were added, and no inobject properties were removed, setting | 2279 // If no fields were added, and no inobject properties were removed, setting |
2277 // the map is sufficient. | 2280 // the map is sufficient. |
2278 if (target_inobject == inobject_properties()) return false; | 2281 if (target_inobject == inobject_properties()) return false; |
2279 // In-object slack tracking may have reduced the object size of the new map. | 2282 // In-object slack tracking may have reduced the object size of the new map. |
2280 // In that case, succeed if all existing fields were inobject, and they still | 2283 // In that case, succeed if all existing fields were inobject, and they still |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 for (int i = 0; i < descriptors; i++) { | 2334 for (int i = 0; i < descriptors; i++) { |
2332 PropertyDetails details = new_descriptors->GetDetails(i); | 2335 PropertyDetails details = new_descriptors->GetDetails(i); |
2333 if (details.type() != FIELD) continue; | 2336 if (details.type() != FIELD) continue; |
2334 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2337 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2335 ASSERT(old_details.type() == CONSTANT_FUNCTION || | 2338 ASSERT(old_details.type() == CONSTANT_FUNCTION || |
2336 old_details.type() == FIELD); | 2339 old_details.type() == FIELD); |
2337 Object* value = old_details.type() == CONSTANT_FUNCTION | 2340 Object* value = old_details.type() == CONSTANT_FUNCTION |
2338 ? old_descriptors->GetValue(i) | 2341 ? old_descriptors->GetValue(i) |
2339 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); | 2342 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); |
2340 if (FLAG_track_double_fields && | 2343 if (FLAG_track_double_fields && |
2341 old_details.representation().IsSmi() && | 2344 !old_details.representation().IsDouble() && |
2342 details.representation().IsDouble()) { | 2345 details.representation().IsDouble()) { |
| 2346 if (old_details.representation().IsNone()) value = Smi::FromInt(0); |
2343 // Objects must be allocated in the old object space, since the | 2347 // Objects must be allocated in the old object space, since the |
2344 // overall number of HeapNumbers needed for the conversion might | 2348 // overall number of HeapNumbers needed for the conversion might |
2345 // exceed the capacity of new space, and we would fail repeatedly | 2349 // exceed the capacity of new space, and we would fail repeatedly |
2346 // trying to migrate the instance. | 2350 // trying to migrate the instance. |
2347 MaybeObject* maybe_storage = | 2351 MaybeObject* maybe_storage = |
2348 value->AllocateNewStorageFor(heap, details.representation(), TENURED); | 2352 value->AllocateNewStorageFor(heap, details.representation(), TENURED); |
2349 if (!maybe_storage->To(&value)) return maybe_storage; | 2353 if (!maybe_storage->To(&value)) return maybe_storage; |
2350 } | 2354 } |
2351 ASSERT(!(FLAG_track_double_fields && | 2355 ASSERT(!(FLAG_track_double_fields && |
2352 details.representation().IsDouble() && | 2356 details.representation().IsDouble() && |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2385 } | 2389 } |
2386 | 2390 |
2387 | 2391 |
2388 MaybeObject* JSObject::GeneralizeFieldRepresentation( | 2392 MaybeObject* JSObject::GeneralizeFieldRepresentation( |
2389 int modify_index, | 2393 int modify_index, |
2390 Representation new_representation) { | 2394 Representation new_representation) { |
2391 Map* new_map; | 2395 Map* new_map; |
2392 MaybeObject* maybe_new_map = | 2396 MaybeObject* maybe_new_map = |
2393 map()->GeneralizeRepresentation(modify_index, new_representation); | 2397 map()->GeneralizeRepresentation(modify_index, new_representation); |
2394 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 2398 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
2395 ASSERT(map() != new_map || new_map->FindRootMap()->is_deprecated()); | 2399 if (map() == new_map) return this; |
2396 | 2400 |
2397 return MigrateToMap(new_map); | 2401 return MigrateToMap(new_map); |
2398 } | 2402 } |
2399 | 2403 |
2400 | 2404 |
2401 int Map::NumberOfFields() { | 2405 int Map::NumberOfFields() { |
2402 DescriptorArray* descriptors = instance_descriptors(); | 2406 DescriptorArray* descriptors = instance_descriptors(); |
2403 int result = 0; | 2407 int result = 0; |
2404 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2408 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2405 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2409 if (descriptors->GetDetails(i).type() == FIELD) result++; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2562 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. | 2566 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. |
2563 // - Otherwise, invalidate the outdated transition target from |updated|, and | 2567 // - Otherwise, invalidate the outdated transition target from |updated|, and |
2564 // replace its transition tree with a new branch for the updated descriptors. | 2568 // replace its transition tree with a new branch for the updated descriptors. |
2565 MaybeObject* Map::GeneralizeRepresentation(int modify_index, | 2569 MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
2566 Representation new_representation) { | 2570 Representation new_representation) { |
2567 Map* old_map = this; | 2571 Map* old_map = this; |
2568 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 2572 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
2569 Representation old_representation = | 2573 Representation old_representation = |
2570 old_descriptors->GetDetails(modify_index).representation(); | 2574 old_descriptors->GetDetails(modify_index).representation(); |
2571 | 2575 |
2572 if (old_representation.IsNone()) { | 2576 // It's fine to transition from None to anything but double without any |
2573 UNREACHABLE(); | 2577 // modification to the object, because the default uninitialized value for |
| 2578 // representation None can be overwritten by both smi and tagged values. |
| 2579 // Doubles, however, would require a box allocation. |
| 2580 if (old_representation.IsNone() && |
| 2581 !new_representation.IsNone() && |
| 2582 !new_representation.IsDouble()) { |
| 2583 if (FLAG_trace_generalization) { |
| 2584 PrintF("initializing representation %i: %p -> %s\n", |
| 2585 modify_index, |
| 2586 static_cast<void*>(this), |
| 2587 new_representation.Mnemonic()); |
| 2588 } |
2574 old_descriptors->SetRepresentation(modify_index, new_representation); | 2589 old_descriptors->SetRepresentation(modify_index, new_representation); |
2575 return this; | 2590 return old_map; |
2576 } | 2591 } |
2577 | 2592 |
2578 int descriptors = old_map->NumberOfOwnDescriptors(); | 2593 int descriptors = old_map->NumberOfOwnDescriptors(); |
2579 Map* root_map = old_map->FindRootMap(); | 2594 Map* root_map = old_map->FindRootMap(); |
2580 | 2595 |
2581 // Check the state of the root map. | 2596 // Check the state of the root map. |
2582 if (!old_map->EquivalentToForTransition(root_map)) { | 2597 if (!old_map->EquivalentToForTransition(root_map)) { |
2583 return CopyGeneralizeAllRepresentations(); | 2598 return CopyGeneralizeAllRepresentations(); |
2584 } | 2599 } |
2585 | 2600 |
2586 int verbatim = root_map->NumberOfOwnDescriptors(); | 2601 int verbatim = root_map->NumberOfOwnDescriptors(); |
2587 | 2602 |
2588 Map* updated = root_map->FindUpdatedMap( | 2603 Map* updated = root_map->FindUpdatedMap( |
2589 verbatim, descriptors, old_descriptors); | 2604 verbatim, descriptors, old_descriptors); |
2590 if (updated == NULL) return CopyGeneralizeAllRepresentations(); | 2605 if (updated == NULL) return CopyGeneralizeAllRepresentations(); |
2591 | 2606 |
2592 DescriptorArray* updated_descriptors = updated->instance_descriptors(); | 2607 DescriptorArray* updated_descriptors = updated->instance_descriptors(); |
2593 | 2608 |
2594 int valid = updated->NumberOfOwnDescriptors(); | 2609 int valid = updated->NumberOfOwnDescriptors(); |
2595 if (updated_descriptors->IsMoreGeneralThan( | 2610 if (updated_descriptors->IsMoreGeneralThan( |
2596 verbatim, valid, descriptors, old_descriptors)) { | 2611 verbatim, valid, descriptors, old_descriptors)) { |
2597 Representation updated_representation = | 2612 Representation updated_representation = |
2598 updated_descriptors->GetDetails(modify_index).representation(); | 2613 updated_descriptors->GetDetails(modify_index).representation(); |
2599 if (new_representation.fits_into(updated_representation)) { | 2614 if (new_representation.fits_into(updated_representation)) { |
2600 if (FLAG_trace_generalization && | 2615 if (FLAG_trace_generalization && |
2601 !(modify_index == 0 && new_representation.IsSmi())) { | 2616 !(modify_index == 0 && new_representation.IsNone())) { |
2602 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2617 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2603 PrintF("migrating to existing map %p(%s) -> %p(%s)\n", | 2618 PrintF("migrating to existing map %p(%s) -> %p(%s)\n", |
2604 static_cast<void*>(this), | 2619 static_cast<void*>(this), |
2605 old_details.representation().Mnemonic(), | 2620 old_details.representation().Mnemonic(), |
2606 static_cast<void*>(updated), | 2621 static_cast<void*>(updated), |
2607 updated_representation.Mnemonic()); | 2622 updated_representation.Mnemonic()); |
2608 } | 2623 } |
2609 return updated; | 2624 return updated; |
2610 } | 2625 } |
2611 } | 2626 } |
(...skipping 17 matching lines...) Expand all Loading... |
2629 int split_descriptors = split_map->NumberOfOwnDescriptors(); | 2644 int split_descriptors = split_map->NumberOfOwnDescriptors(); |
2630 // This is shadowed by |updated_descriptors| being more general than | 2645 // This is shadowed by |updated_descriptors| being more general than |
2631 // |old_descriptors|. | 2646 // |old_descriptors|. |
2632 ASSERT(descriptors != split_descriptors); | 2647 ASSERT(descriptors != split_descriptors); |
2633 | 2648 |
2634 int descriptor = split_descriptors; | 2649 int descriptor = split_descriptors; |
2635 split_map->DeprecateTarget( | 2650 split_map->DeprecateTarget( |
2636 old_descriptors->GetKey(descriptor), new_descriptors); | 2651 old_descriptors->GetKey(descriptor), new_descriptors); |
2637 | 2652 |
2638 if (FLAG_trace_generalization && | 2653 if (FLAG_trace_generalization && |
2639 !(modify_index == 0 && new_representation.IsSmi())) { | 2654 !(modify_index == 0 && new_representation.IsNone())) { |
2640 PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n", | 2655 PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n", |
2641 modify_index, | 2656 modify_index, |
2642 static_cast<void*>(this), | 2657 static_cast<void*>(this), |
2643 old_representation.Mnemonic(), | 2658 old_representation.Mnemonic(), |
2644 static_cast<void*>(new_descriptors), | 2659 static_cast<void*>(new_descriptors), |
2645 updated_representation.Mnemonic(), | 2660 updated_representation.Mnemonic(), |
2646 descriptors - descriptor); | 2661 descriptors - descriptor); |
2647 } | 2662 } |
2648 | 2663 |
2649 Map* new_map = split_map; | 2664 Map* new_map = split_map; |
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3921 // callback setter removed. The two lines looking up the LookupResult | 3936 // callback setter removed. The two lines looking up the LookupResult |
3922 // result are also added. If one of the functions is changed, the other | 3937 // result are also added. If one of the functions is changed, the other |
3923 // should be. | 3938 // should be. |
3924 // Note that this method cannot be used to set the prototype of a function | 3939 // Note that this method cannot be used to set the prototype of a function |
3925 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" | 3940 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" |
3926 // doesn't handle function prototypes correctly. | 3941 // doesn't handle function prototypes correctly. |
3927 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( | 3942 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
3928 Handle<JSObject> object, | 3943 Handle<JSObject> object, |
3929 Handle<Name> key, | 3944 Handle<Name> key, |
3930 Handle<Object> value, | 3945 Handle<Object> value, |
3931 PropertyAttributes attributes) { | 3946 PropertyAttributes attributes, |
| 3947 ValueType value_type) { |
3932 CALL_HEAP_FUNCTION( | 3948 CALL_HEAP_FUNCTION( |
3933 object->GetIsolate(), | 3949 object->GetIsolate(), |
3934 object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), | 3950 object->SetLocalPropertyIgnoreAttributes( |
| 3951 *key, *value, attributes, value_type), |
3935 Object); | 3952 Object); |
3936 } | 3953 } |
3937 | 3954 |
3938 | 3955 |
3939 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 3956 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
3940 Name* name_raw, | 3957 Name* name_raw, |
3941 Object* value_raw, | 3958 Object* value_raw, |
3942 PropertyAttributes attributes) { | 3959 PropertyAttributes attributes, |
| 3960 ValueType value_type) { |
3943 // Make sure that the top context does not change when doing callbacks or | 3961 // Make sure that the top context does not change when doing callbacks or |
3944 // interceptor calls. | 3962 // interceptor calls. |
3945 AssertNoContextChange ncc; | 3963 AssertNoContextChange ncc; |
3946 Isolate* isolate = GetIsolate(); | 3964 Isolate* isolate = GetIsolate(); |
3947 LookupResult lookup(isolate); | 3965 LookupResult lookup(isolate); |
3948 LocalLookup(name_raw, &lookup, true); | 3966 LocalLookup(name_raw, &lookup, true); |
3949 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); | 3967 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); |
3950 // Check access rights if needed. | 3968 // Check access rights if needed. |
3951 if (IsAccessCheckNeeded()) { | 3969 if (IsAccessCheckNeeded()) { |
3952 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 3970 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
3953 return SetPropertyWithFailedAccessCheck(&lookup, | 3971 return SetPropertyWithFailedAccessCheck(&lookup, |
3954 name_raw, | 3972 name_raw, |
3955 value_raw, | 3973 value_raw, |
3956 false, | 3974 false, |
3957 kNonStrictMode); | 3975 kNonStrictMode); |
3958 } | 3976 } |
3959 } | 3977 } |
3960 | 3978 |
3961 if (IsJSGlobalProxy()) { | 3979 if (IsJSGlobalProxy()) { |
3962 Object* proto = GetPrototype(); | 3980 Object* proto = GetPrototype(); |
3963 if (proto->IsNull()) return value_raw; | 3981 if (proto->IsNull()) return value_raw; |
3964 ASSERT(proto->IsJSGlobalObject()); | 3982 ASSERT(proto->IsJSGlobalObject()); |
3965 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 3983 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
3966 name_raw, | 3984 name_raw, |
3967 value_raw, | 3985 value_raw, |
3968 attributes); | 3986 attributes, |
| 3987 value_type); |
3969 } | 3988 } |
3970 | 3989 |
3971 // Check for accessor in prototype chain removed here in clone. | 3990 // Check for accessor in prototype chain removed here in clone. |
3972 if (!lookup.IsFound()) { | 3991 if (!lookup.IsFound()) { |
3973 // Neither properties nor transitions found. | 3992 // Neither properties nor transitions found. |
3974 return AddProperty(name_raw, value_raw, attributes, kNonStrictMode); | 3993 return AddProperty( |
| 3994 name_raw, value_raw, attributes, kNonStrictMode, |
| 3995 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type); |
3975 } | 3996 } |
3976 | 3997 |
3977 // From this point on everything needs to be handlified. | 3998 // From this point on everything needs to be handlified. |
3978 HandleScope scope(isolate); | 3999 HandleScope scope(isolate); |
3979 Handle<JSObject> self(this); | 4000 Handle<JSObject> self(this); |
3980 Handle<Name> name(name_raw); | 4001 Handle<Name> name(name_raw); |
3981 Handle<Object> value(value_raw, isolate); | 4002 Handle<Object> value(value_raw, isolate); |
3982 | 4003 |
3983 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 4004 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
3984 PropertyAttributes old_attributes = ABSENT; | 4005 PropertyAttributes old_attributes = ABSENT; |
3985 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4006 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
3986 if (is_observed) { | 4007 if (is_observed) { |
3987 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); | 4008 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); |
3988 old_attributes = lookup.GetAttributes(); | 4009 old_attributes = lookup.GetAttributes(); |
3989 } | 4010 } |
3990 | 4011 |
3991 // Check of IsReadOnly removed from here in clone. | 4012 // Check of IsReadOnly removed from here in clone. |
3992 MaybeObject* result = *value; | 4013 MaybeObject* result = *value; |
3993 switch (lookup.type()) { | 4014 switch (lookup.type()) { |
3994 case NORMAL: { | 4015 case NORMAL: { |
3995 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 4016 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
3996 result = self->SetNormalizedProperty(*name, *value, details); | 4017 result = self->SetNormalizedProperty(*name, *value, details); |
3997 break; | 4018 break; |
3998 } | 4019 } |
3999 case FIELD: { | 4020 case FIELD: { |
4000 Representation representation = lookup.representation(); | 4021 Representation representation = lookup.representation(); |
4001 if (!value->FitsRepresentation(representation)) { | 4022 Representation value_representation = |
| 4023 value->OptimalRepresentation(value_type); |
| 4024 if (!value_representation.fits_into(representation)) { |
4002 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( | 4025 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( |
4003 lookup.GetDescriptorIndex(), value->OptimalRepresentation()); | 4026 lookup.GetDescriptorIndex(), value_representation); |
4004 if (maybe_failure->IsFailure()) return maybe_failure; | 4027 if (maybe_failure->IsFailure()) return maybe_failure; |
4005 DescriptorArray* desc = self->map()->instance_descriptors(); | 4028 DescriptorArray* desc = self->map()->instance_descriptors(); |
4006 int descriptor = lookup.GetDescriptorIndex(); | 4029 int descriptor = lookup.GetDescriptorIndex(); |
4007 representation = desc->GetDetails(descriptor).representation(); | 4030 representation = desc->GetDetails(descriptor).representation(); |
4008 } | 4031 } |
4009 if (FLAG_track_double_fields && representation.IsDouble()) { | 4032 if (FLAG_track_double_fields && representation.IsDouble()) { |
4010 HeapNumber* storage = | 4033 HeapNumber* storage = |
4011 HeapNumber::cast(self->RawFastPropertyAt( | 4034 HeapNumber::cast(self->RawFastPropertyAt( |
4012 lookup.GetFieldIndex().field_index())); | 4035 lookup.GetFieldIndex().field_index())); |
4013 storage->set_value(value->Number()); | 4036 storage->set_value(value->Number()); |
(...skipping 20 matching lines...) Expand all Loading... |
4034 case TRANSITION: { | 4057 case TRANSITION: { |
4035 Map* transition_map = lookup.GetTransitionTarget(); | 4058 Map* transition_map = lookup.GetTransitionTarget(); |
4036 int descriptor = transition_map->LastAdded(); | 4059 int descriptor = transition_map->LastAdded(); |
4037 | 4060 |
4038 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 4061 DescriptorArray* descriptors = transition_map->instance_descriptors(); |
4039 PropertyDetails details = descriptors->GetDetails(descriptor); | 4062 PropertyDetails details = descriptors->GetDetails(descriptor); |
4040 | 4063 |
4041 if (details.type() == FIELD) { | 4064 if (details.type() == FIELD) { |
4042 if (attributes == details.attributes()) { | 4065 if (attributes == details.attributes()) { |
4043 Representation representation = details.representation(); | 4066 Representation representation = details.representation(); |
4044 if (!value->FitsRepresentation(representation)) { | 4067 Representation value_representation = |
| 4068 value->OptimalRepresentation(value_type); |
| 4069 if (!value_representation.fits_into(representation)) { |
4045 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( | 4070 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( |
4046 descriptor, value->OptimalRepresentation()); | 4071 descriptor, value_representation); |
4047 if (!maybe_map->To(&transition_map)) return maybe_map; | 4072 if (!maybe_map->To(&transition_map)) return maybe_map; |
4048 Object* back = transition_map->GetBackPointer(); | 4073 Object* back = transition_map->GetBackPointer(); |
4049 if (back->IsMap()) { | 4074 if (back->IsMap()) { |
4050 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back)); | 4075 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back)); |
4051 if (maybe_failure->IsFailure()) return maybe_failure; | 4076 if (maybe_failure->IsFailure()) return maybe_failure; |
4052 } | 4077 } |
4053 DescriptorArray* desc = transition_map->instance_descriptors(); | 4078 DescriptorArray* desc = transition_map->instance_descriptors(); |
4054 int descriptor = transition_map->LastAdded(); | 4079 int descriptor = transition_map->LastAdded(); |
4055 representation = desc->GetDetails(descriptor).representation(); | 4080 representation = desc->GetDetails(descriptor).representation(); |
4056 } | 4081 } |
(...skipping 11623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15680 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 15705 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
15681 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 15706 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
15682 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 15707 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
15683 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 15708 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
15684 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 15709 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
15685 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 15710 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
15686 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 15711 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
15687 } | 15712 } |
15688 | 15713 |
15689 } } // namespace v8::internal | 15714 } } // namespace v8::internal |
OLD | NEW |