Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/objects.cc

Issue 14721009: Track computed literal properties. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698