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

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

Powered by Google App Engine
This is Rietveld 408576698