Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // 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 |