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