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

Side by Side Diff: src/objects.cc

Issue 23252008: Get rid of ConvertFieldToDescriptor. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment Created 7 years, 3 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-inl.h » ('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 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 } 1920 }
1921 } 1921 }
1922 return true; 1922 return true;
1923 } 1923 }
1924 1924
1925 1925
1926 MaybeObject* JSObject::AddFastProperty(Name* name, 1926 MaybeObject* JSObject::AddFastProperty(Name* name,
1927 Object* value, 1927 Object* value,
1928 PropertyAttributes attributes, 1928 PropertyAttributes attributes,
1929 StoreFromKeyed store_mode, 1929 StoreFromKeyed store_mode,
1930 ValueType value_type) { 1930 ValueType value_type,
1931 TransitionFlag flag) {
1931 ASSERT(!IsJSGlobalProxy()); 1932 ASSERT(!IsJSGlobalProxy());
1932 ASSERT(DescriptorArray::kNotFound == 1933 ASSERT(DescriptorArray::kNotFound ==
1933 map()->instance_descriptors()->Search( 1934 map()->instance_descriptors()->Search(
1934 name, map()->NumberOfOwnDescriptors())); 1935 name, map()->NumberOfOwnDescriptors()));
1935 1936
1936 // Normalize the object if the name is an actual name (not the 1937 // Normalize the object if the name is an actual name (not the
1937 // hidden strings) and is not a real identifier. 1938 // hidden strings) and is not a real identifier.
1938 // Normalize the object if it will have too many fast properties. 1939 // Normalize the object if it will have too many fast properties.
1939 Isolate* isolate = GetHeap()->isolate(); 1940 Isolate* isolate = GetHeap()->isolate();
1940 if ((!name->IsSymbol() && !IsIdentifier(isolate->unicode_cache(), name) 1941 if ((!name->IsSymbol() &&
1941 && name != isolate->heap()->hidden_string()) || 1942 !IsIdentifier(isolate->unicode_cache(), name) &&
1942 (map()->unused_property_fields() == 0 && 1943 name != isolate->heap()->hidden_string()) ||
1943 TooManyFastProperties(properties()->length(), store_mode))) { 1944 TooManyFastProperties(store_mode)) {
1944 Object* obj; 1945 MaybeObject* maybe_failure =
1945 MaybeObject* maybe_obj =
1946 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1946 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1947 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1947 if (maybe_failure->IsFailure()) return maybe_failure;
1948
1949 return AddSlowProperty(name, value, attributes); 1948 return AddSlowProperty(name, value, attributes);
1950 } 1949 }
1951 1950
1952 // Compute the new index for new field. 1951 // Compute the new index for new field.
1953 int index = map()->NextFreePropertyIndex(); 1952 int index = map()->NextFreePropertyIndex();
1954 1953
1955 // Allocate new instance descriptors with (name, index) added 1954 // Allocate new instance descriptors with (name, index) added
1956 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1955 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1957 Representation representation = value->OptimalRepresentation(value_type); 1956 Representation representation = value->OptimalRepresentation(value_type);
1958 1957
1959 FieldDescriptor new_field(name, index, attributes, representation); 1958 FieldDescriptor new_field(name, index, attributes, representation);
1960 1959
1961 ASSERT(index < map()->inobject_properties() || 1960 ASSERT(index < map()->inobject_properties() ||
1962 (index - map()->inobject_properties()) < properties()->length() || 1961 (index - map()->inobject_properties()) < properties()->length() ||
1963 map()->unused_property_fields() == 0); 1962 map()->unused_property_fields() == 0);
1964 1963
1965 FixedArray* values = NULL; 1964 FixedArray* values = NULL;
1966 1965
1967 // TODO(verwaest): Merge with AddFastPropertyUsingMap. 1966 // TODO(verwaest): Merge with AddFastPropertyUsingMap.
1968 if (map()->unused_property_fields() == 0) { 1967 if (map()->unused_property_fields() == 0) {
1969 // Make room for the new value 1968 // Make room for the new value
1970 MaybeObject* maybe_values = 1969 MaybeObject* maybe_values =
1971 properties()->CopySize(properties()->length() + kFieldsAdded); 1970 properties()->CopySize(properties()->length() + kFieldsAdded);
1972 if (!maybe_values->To(&values)) return maybe_values; 1971 if (!maybe_values->To(&values)) return maybe_values;
1973 } 1972 }
1974 1973
1975 TransitionFlag flag = INSERT_TRANSITION;
1976
1977 Heap* heap = isolate->heap(); 1974 Heap* heap = isolate->heap();
1978 1975
1979 Object* storage; 1976 Object* storage;
1980 MaybeObject* maybe_storage = 1977 MaybeObject* maybe_storage =
1981 value->AllocateNewStorageFor(heap, representation); 1978 value->AllocateNewStorageFor(heap, representation);
1982 if (!maybe_storage->To(&storage)) return maybe_storage; 1979 if (!maybe_storage->To(&storage)) return maybe_storage;
1983 1980
1984 // Note that Map::CopyAddDescriptor has side-effects, the new map is already 1981 // Note that Map::CopyAddDescriptor has side-effects, the new map is already
1985 // inserted in the transition tree. No more allocations that might fail are 1982 // inserted in the transition tree. No more allocations that might fail are
1986 // allowed after this point. 1983 // allowed after this point.
(...skipping 12 matching lines...) Expand all
1999 set_map(new_map); 1996 set_map(new_map);
2000 1997
2001 FastPropertyAtPut(index, storage); 1998 FastPropertyAtPut(index, storage);
2002 return value; 1999 return value;
2003 } 2000 }
2004 2001
2005 2002
2006 MaybeObject* JSObject::AddConstantProperty( 2003 MaybeObject* JSObject::AddConstantProperty(
2007 Name* name, 2004 Name* name,
2008 Object* constant, 2005 Object* constant,
2009 PropertyAttributes attributes) { 2006 PropertyAttributes attributes,
2007 TransitionFlag initial_flag) {
2010 // Allocate new instance descriptors with (name, constant) added 2008 // Allocate new instance descriptors with (name, constant) added
2011 ConstantDescriptor d(name, constant, attributes); 2009 ConstantDescriptor d(name, constant, attributes);
2012 2010
2013 TransitionFlag flag = 2011 TransitionFlag flag =
2014 // Do not add transitions to global objects. 2012 // Do not add transitions to global objects.
2015 (IsGlobalObject() || 2013 (IsGlobalObject() ||
2016 // Don't add transitions to special properties with non-trivial 2014 // Don't add transitions to special properties with non-trivial
2017 // attributes. 2015 // attributes.
2018 attributes != NONE) 2016 attributes != NONE)
2019 ? OMIT_TRANSITION 2017 ? OMIT_TRANSITION
2020 : INSERT_TRANSITION; 2018 : initial_flag;
2021 2019
2022 Map* new_map; 2020 Map* new_map;
2023 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); 2021 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
2024 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2022 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2025 2023
2026 set_map(new_map); 2024 set_map(new_map);
2027 return constant; 2025 return constant;
2028 } 2026 }
2029 2027
2030 2028
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 } 2068 }
2071 2069
2072 2070
2073 MaybeObject* JSObject::AddProperty(Name* name, 2071 MaybeObject* JSObject::AddProperty(Name* name,
2074 Object* value, 2072 Object* value,
2075 PropertyAttributes attributes, 2073 PropertyAttributes attributes,
2076 StrictModeFlag strict_mode, 2074 StrictModeFlag strict_mode,
2077 JSReceiver::StoreFromKeyed store_mode, 2075 JSReceiver::StoreFromKeyed store_mode,
2078 ExtensibilityCheck extensibility_check, 2076 ExtensibilityCheck extensibility_check,
2079 ValueType value_type, 2077 ValueType value_type,
2080 StoreMode mode) { 2078 StoreMode mode,
2079 TransitionFlag transition_flag) {
2081 ASSERT(!IsJSGlobalProxy()); 2080 ASSERT(!IsJSGlobalProxy());
2082 Map* map_of_this = map(); 2081 Map* map_of_this = map();
2083 Heap* heap = GetHeap(); 2082 Heap* heap = GetHeap();
2084 Isolate* isolate = heap->isolate(); 2083 Isolate* isolate = heap->isolate();
2085 MaybeObject* result; 2084 MaybeObject* result;
2086 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && 2085 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2087 !map_of_this->is_extensible()) { 2086 !map_of_this->is_extensible()) {
2088 if (strict_mode == kNonStrictMode) { 2087 if (strict_mode == kNonStrictMode) {
2089 return value; 2088 return value;
2090 } else { 2089 } else {
2091 Handle<Object> args[1] = {Handle<Name>(name)}; 2090 Handle<Object> args[1] = {Handle<Name>(name)};
2092 return isolate->Throw( 2091 return isolate->Throw(
2093 *isolate->factory()->NewTypeError("object_not_extensible", 2092 *isolate->factory()->NewTypeError("object_not_extensible",
2094 HandleVector(args, 1))); 2093 HandleVector(args, 1)));
2095 } 2094 }
2096 } 2095 }
2097 2096
2098 if (HasFastProperties()) { 2097 if (HasFastProperties()) {
2099 // Ensure the descriptor array does not get too big. 2098 // Ensure the descriptor array does not get too big.
2100 if (map_of_this->NumberOfOwnDescriptors() < 2099 if (map_of_this->NumberOfOwnDescriptors() <
2101 DescriptorArray::kMaxNumberOfDescriptors) { 2100 DescriptorArray::kMaxNumberOfDescriptors) {
2102 // TODO(verwaest): Support other constants. 2101 // TODO(verwaest): Support other constants.
2103 // if (mode == ALLOW_AS_CONSTANT && 2102 // if (mode == ALLOW_AS_CONSTANT &&
2104 // !value->IsTheHole() && 2103 // !value->IsTheHole() &&
2105 // !value->IsConsString()) { 2104 // !value->IsConsString()) {
2106 if (value->IsJSFunction()) { 2105 if (value->IsJSFunction()) {
2107 result = AddConstantProperty(name, value, attributes); 2106 result = AddConstantProperty(name, value, attributes, transition_flag);
2108 } else { 2107 } else {
2109 result = AddFastProperty( 2108 result = AddFastProperty(
2110 name, value, attributes, store_mode, value_type); 2109 name, value, attributes, store_mode, value_type, transition_flag);
2111 } 2110 }
2112 } else { 2111 } else {
2113 // Normalize the object to prevent very large instance descriptors. 2112 // Normalize the object to prevent very large instance descriptors.
2114 // This eliminates unwanted N^2 allocation and lookup behavior. 2113 // This eliminates unwanted N^2 allocation and lookup behavior.
2115 Object* obj; 2114 Object* obj;
2116 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2115 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2117 if (!maybe->To(&obj)) return maybe; 2116 if (!maybe->To(&obj)) return maybe;
2118 result = AddSlowProperty(name, value, attributes); 2117 result = AddSlowProperty(name, value, attributes);
2119 } 2118 }
2120 } else { 2119 } else {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2204 if (old_index != -1) { 2203 if (old_index != -1) {
2205 // All calls to ReplaceSlowProperty have had all transitions removed. 2204 // All calls to ReplaceSlowProperty have had all transitions removed.
2206 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2205 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2207 } 2206 }
2208 2207
2209 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2208 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2210 return SetNormalizedProperty(name, value, new_details); 2209 return SetNormalizedProperty(name, value, new_details);
2211 } 2210 }
2212 2211
2213 2212
2214 MaybeObject* JSObject::ConvertDescriptorToField(Name* name,
2215 Object* new_value,
2216 PropertyAttributes attributes,
2217 TransitionFlag flag) {
2218 if (map()->unused_property_fields() == 0 &&
2219 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
2220 Object* obj;
2221 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2222 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2223 return ReplaceSlowProperty(name, new_value, attributes);
2224 }
2225
2226 Representation representation = IsJSContextExtensionObject()
2227 ? Representation::Tagged() : new_value->OptimalRepresentation();
2228 int index = map()->NextFreePropertyIndex();
2229 FieldDescriptor new_field(name, index, attributes, representation);
2230
2231 // Make a new map for the object.
2232 Map* new_map;
2233 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, flag);
2234 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2235
2236 // Make new properties array if necessary.
2237 FixedArray* new_properties = NULL;
2238 int new_unused_property_fields = map()->unused_property_fields() - 1;
2239 if (map()->unused_property_fields() == 0) {
2240 new_unused_property_fields = kFieldsAdded - 1;
2241 MaybeObject* maybe_new_properties =
2242 properties()->CopySize(properties()->length() + kFieldsAdded);
2243 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties;
2244 }
2245
2246 Heap* heap = GetHeap();
2247 Object* storage;
2248 MaybeObject* maybe_storage =
2249 new_value->AllocateNewStorageFor(heap, representation);
2250 if (!maybe_storage->To(&storage)) return maybe_storage;
2251
2252 // Update pointers to commit changes.
2253 // Object points to the new map.
2254 new_map->set_unused_property_fields(new_unused_property_fields);
2255 set_map(new_map);
2256 if (new_properties != NULL) {
2257 set_properties(new_properties);
2258 }
2259 FastPropertyAtPut(index, storage);
2260 return new_value;
2261 }
2262
2263
2264 const char* Representation::Mnemonic() const { 2213 const char* Representation::Mnemonic() const {
2265 switch (kind_) { 2214 switch (kind_) {
2266 case kNone: return "v"; 2215 case kNone: return "v";
2267 case kTagged: return "t"; 2216 case kTagged: return "t";
2268 case kSmi: return "s"; 2217 case kSmi: return "s";
2269 case kDouble: return "d"; 2218 case kDouble: return "d";
2270 case kInteger32: return "i"; 2219 case kInteger32: return "i";
2271 case kHeapObject: return "h"; 2220 case kHeapObject: return "h";
2272 case kExternal: return "x"; 2221 case kExternal: return "x";
2273 default: 2222 default:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 if (!maybe_array->To(&array)) return maybe_array; 2349 if (!maybe_array->To(&array)) return maybe_array;
2401 2350
2402 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2351 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2403 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2352 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2404 int descriptors = new_map->NumberOfOwnDescriptors(); 2353 int descriptors = new_map->NumberOfOwnDescriptors();
2405 2354
2406 for (int i = 0; i < descriptors; i++) { 2355 for (int i = 0; i < descriptors; i++) {
2407 PropertyDetails details = new_descriptors->GetDetails(i); 2356 PropertyDetails details = new_descriptors->GetDetails(i);
2408 if (details.type() != FIELD) continue; 2357 if (details.type() != FIELD) continue;
2409 PropertyDetails old_details = old_descriptors->GetDetails(i); 2358 PropertyDetails old_details = old_descriptors->GetDetails(i);
2359 if (old_details.type() == CALLBACKS) {
2360 ASSERT(details.representation().IsTagged());
2361 continue;
2362 }
2410 ASSERT(old_details.type() == CONSTANT || 2363 ASSERT(old_details.type() == CONSTANT ||
2411 old_details.type() == FIELD); 2364 old_details.type() == FIELD);
2412 Object* value = old_details.type() == CONSTANT 2365 Object* value = old_details.type() == CONSTANT
2413 ? old_descriptors->GetValue(i) 2366 ? old_descriptors->GetValue(i)
2414 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2367 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2415 if (FLAG_track_double_fields && 2368 if (FLAG_track_double_fields &&
2416 !old_details.representation().IsDouble() && 2369 !old_details.representation().IsDouble() &&
2417 details.representation().IsDouble()) { 2370 details.representation().IsDouble()) {
2418 if (old_details.representation().IsNone()) value = Smi::FromInt(0); 2371 if (old_details.representation().IsNone()) value = Smi::FromInt(0);
2419 // Objects must be allocated in the old object space, since the 2372 // Objects must be allocated in the old object space, since the
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2434 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2482 if (descriptors->GetDetails(i).type() == FIELD) result++; 2435 if (descriptors->GetDetails(i).type() == FIELD) result++;
2483 } 2436 }
2484 return result; 2437 return result;
2485 } 2438 }
2486 2439
2487 2440
2488 MaybeObject* Map::CopyGeneralizeAllRepresentations( 2441 MaybeObject* Map::CopyGeneralizeAllRepresentations(
2489 int modify_index, 2442 int modify_index,
2490 StoreMode store_mode, 2443 StoreMode store_mode,
2444 PropertyAttributes attributes,
2491 const char* reason) { 2445 const char* reason) {
2492 Map* new_map; 2446 Map* new_map;
2493 MaybeObject* maybe_map = this->Copy(); 2447 MaybeObject* maybe_map = this->Copy();
2494 if (!maybe_map->To(&new_map)) return maybe_map; 2448 if (!maybe_map->To(&new_map)) return maybe_map;
2495 2449
2496 DescriptorArray* descriptors = new_map->instance_descriptors(); 2450 DescriptorArray* descriptors = new_map->instance_descriptors();
2497 descriptors->InitializeRepresentations(Representation::Tagged()); 2451 descriptors->InitializeRepresentations(Representation::Tagged());
2498 2452
2499 // Unless the instance is being migrated, ensure that modify_index is a field. 2453 // Unless the instance is being migrated, ensure that modify_index is a field.
2500 PropertyDetails details = descriptors->GetDetails(modify_index); 2454 PropertyDetails details = descriptors->GetDetails(modify_index);
2501 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2455 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2502 FieldDescriptor d(descriptors->GetKey(modify_index), 2456 FieldDescriptor d(descriptors->GetKey(modify_index),
2503 new_map->NumberOfFields(), 2457 new_map->NumberOfFields(),
2504 details.attributes(), 2458 attributes,
2505 Representation::Tagged()); 2459 Representation::Tagged());
2506 d.SetSortedKeyIndex(details.pointer()); 2460 d.SetSortedKeyIndex(details.pointer());
2507 descriptors->Set(modify_index, &d); 2461 descriptors->Set(modify_index, &d);
2508 int unused_property_fields = new_map->unused_property_fields() - 1; 2462 int unused_property_fields = new_map->unused_property_fields() - 1;
2509 if (unused_property_fields < 0) { 2463 if (unused_property_fields < 0) {
2510 unused_property_fields += JSObject::kFieldsAdded; 2464 unused_property_fields += JSObject::kFieldsAdded;
2511 } 2465 }
2512 new_map->set_unused_property_fields(unused_property_fields); 2466 new_map->set_unused_property_fields(unused_property_fields);
2513 } 2467 }
2514 2468
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2659 // |split_map|, the first map who's descriptor array does not match the merged 2613 // |split_map|, the first map who's descriptor array does not match the merged
2660 // descriptor array. 2614 // descriptor array.
2661 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2615 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2662 // - Otherwise, invalidate the outdated transition target from |updated|, and 2616 // - Otherwise, invalidate the outdated transition target from |updated|, and
2663 // replace its transition tree with a new branch for the updated descriptors. 2617 // replace its transition tree with a new branch for the updated descriptors.
2664 MaybeObject* Map::GeneralizeRepresentation(int modify_index, 2618 MaybeObject* Map::GeneralizeRepresentation(int modify_index,
2665 Representation new_representation, 2619 Representation new_representation,
2666 StoreMode store_mode) { 2620 StoreMode store_mode) {
2667 Map* old_map = this; 2621 Map* old_map = this;
2668 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2622 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2669 Representation old_representation = 2623 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2670 old_descriptors->GetDetails(modify_index).representation(); 2624 Representation old_representation = old_details.representation();
2671 2625
2672 // It's fine to transition from None to anything but double without any 2626 // It's fine to transition from None to anything but double without any
2673 // modification to the object, because the default uninitialized value for 2627 // modification to the object, because the default uninitialized value for
2674 // representation None can be overwritten by both smi and tagged values. 2628 // representation None can be overwritten by both smi and tagged values.
2675 // Doubles, however, would require a box allocation. 2629 // Doubles, however, would require a box allocation.
2676 if (old_representation.IsNone() && 2630 if (old_representation.IsNone() &&
2677 !new_representation.IsNone() && 2631 !new_representation.IsNone() &&
2678 !new_representation.IsDouble()) { 2632 !new_representation.IsDouble()) {
2679 old_descriptors->SetRepresentation(modify_index, new_representation); 2633 old_descriptors->SetRepresentation(modify_index, new_representation);
2680 return old_map; 2634 return old_map;
2681 } 2635 }
2682 2636
2683 int descriptors = old_map->NumberOfOwnDescriptors(); 2637 int descriptors = old_map->NumberOfOwnDescriptors();
2684 Map* root_map = old_map->FindRootMap(); 2638 Map* root_map = old_map->FindRootMap();
2685 2639
2686 // Check the state of the root map. 2640 // Check the state of the root map.
2687 if (!old_map->EquivalentToForTransition(root_map)) { 2641 if (!old_map->EquivalentToForTransition(root_map)) {
2688 return CopyGeneralizeAllRepresentations( 2642 return CopyGeneralizeAllRepresentations(
2689 modify_index, store_mode, "not equivalent"); 2643 modify_index, store_mode, old_details.attributes(), "not equivalent");
2690 } 2644 }
2691 2645
2692 int verbatim = root_map->NumberOfOwnDescriptors(); 2646 int verbatim = root_map->NumberOfOwnDescriptors();
2693 2647
2694 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2648 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2695 return CopyGeneralizeAllRepresentations( 2649 return CopyGeneralizeAllRepresentations(
2696 modify_index, store_mode, "root modification"); 2650 modify_index, store_mode,
2651 old_details.attributes(), "root modification");
2697 } 2652 }
2698 2653
2699 Map* updated = root_map->FindUpdatedMap( 2654 Map* updated = root_map->FindUpdatedMap(
2700 verbatim, descriptors, old_descriptors); 2655 verbatim, descriptors, old_descriptors);
2701 if (updated == NULL) { 2656 if (updated == NULL) {
2702 return CopyGeneralizeAllRepresentations( 2657 return CopyGeneralizeAllRepresentations(
2703 modify_index, store_mode, "incompatible"); 2658 modify_index, store_mode, old_details.attributes(), "incompatible");
2704 } 2659 }
2705 2660
2706 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2661 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2707 2662
2708 int valid = updated->NumberOfOwnDescriptors(); 2663 int valid = updated->NumberOfOwnDescriptors();
2709 2664
2710 // Directly change the map if the target map is more general. Ensure that the 2665 // Directly change the map if the target map is more general. Ensure that the
2711 // target type of the modify_index is a FIELD, unless we are migrating. 2666 // target type of the modify_index is a FIELD, unless we are migrating.
2712 if (updated_descriptors->IsMoreGeneralThan( 2667 if (updated_descriptors->IsMoreGeneralThan(
2713 verbatim, valid, descriptors, old_descriptors) && 2668 verbatim, valid, descriptors, old_descriptors) &&
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after
3809 Handle<Name> name, 3764 Handle<Name> name,
3810 Handle<Object> value, 3765 Handle<Object> value,
3811 PropertyAttributes attributes) { 3766 PropertyAttributes attributes) {
3812 Map* transition_map = lookup->GetTransitionTarget(); 3767 Map* transition_map = lookup->GetTransitionTarget();
3813 int descriptor = transition_map->LastAdded(); 3768 int descriptor = transition_map->LastAdded();
3814 3769
3815 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3770 DescriptorArray* descriptors = transition_map->instance_descriptors();
3816 PropertyDetails details = descriptors->GetDetails(descriptor); 3771 PropertyDetails details = descriptors->GetDetails(descriptor);
3817 3772
3818 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3773 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3819 return lookup->holder()->ConvertDescriptorToField( 3774 // AddProperty will either normalize the object, or create a new fast copy
3820 *name, *value, attributes); 3775 // of the map. If we get a fast copy of the map, all field representations
3776 // will be tagged since the transition is omitted.
3777 return lookup->holder()->AddProperty(
3778 *name, *value, attributes, kNonStrictMode,
3779 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3780 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3781 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3821 } 3782 }
3822 3783
3823 // Keep the target CONSTANT if the same value is stored. 3784 // Keep the target CONSTANT if the same value is stored.
3824 // TODO(verwaest): Also support keeping the placeholder 3785 // TODO(verwaest): Also support keeping the placeholder
3825 // (value->IsUninitialized) as constant. 3786 // (value->IsUninitialized) as constant.
3826 if (details.type() == CONSTANT && 3787 if (details.type() == CONSTANT &&
3827 descriptors->GetValue(descriptor) == *value) { 3788 descriptors->GetValue(descriptor) == *value) {
3828 lookup->holder()->set_map(transition_map); 3789 lookup->holder()->set_map(transition_map);
3829 return *value; 3790 return *value;
3830 } 3791 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 storage->set_value(value->Number()); 3836 storage->set_value(value->Number());
3876 return *value; 3837 return *value;
3877 } 3838 }
3878 3839
3879 lookup->holder()->FastPropertyAtPut( 3840 lookup->holder()->FastPropertyAtPut(
3880 lookup->GetFieldIndex().field_index(), *value); 3841 lookup->GetFieldIndex().field_index(), *value);
3881 return *value; 3842 return *value;
3882 } 3843 }
3883 3844
3884 3845
3846 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
3847 Name* name,
3848 Object* value,
3849 PropertyAttributes attributes) {
3850 JSObject* object = lookup->holder();
3851 if (object->TooManyFastProperties()) {
3852 MaybeObject* maybe_failure = object->NormalizeProperties(
3853 CLEAR_INOBJECT_PROPERTIES, 0);
3854 if (maybe_failure->IsFailure()) return maybe_failure;
3855 }
3856
3857 if (!object->HasFastProperties()) {
3858 return object->ReplaceSlowProperty(name, value, attributes);
3859 }
3860
3861 int descriptor_index = lookup->GetDescriptorIndex();
3862 if (lookup->GetAttributes() == attributes) {
3863 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
3864 descriptor_index, Representation::Tagged(), FORCE_FIELD);
3865 if (maybe_failure->IsFailure()) return maybe_failure;
3866 } else {
3867 Map* map;
3868 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations(
3869 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3870 if (!maybe_map->To(&map)) return maybe_map;
3871 MaybeObject* maybe_failure = object->MigrateToMap(map);
3872 if (maybe_failure->IsFailure()) return maybe_failure;
3873 }
3874
3875 DescriptorArray* descriptors = object->map()->instance_descriptors();
3876 int index = descriptors->GetDetails(descriptor_index).field_index();
3877 object->FastPropertyAtPut(index, value);
3878 return value;
3879 }
3880
3881
3882 static MaybeObject* SetPropertyToFieldWithAttributes(
3883 LookupResult* lookup,
3884 Handle<Name> name,
3885 Handle<Object> value,
3886 PropertyAttributes attributes) {
3887 if (lookup->GetAttributes() == attributes) {
3888 if (value->IsUninitialized()) return *value;
3889 return SetPropertyToField(lookup, name, value);
3890 } else {
3891 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
3892 }
3893 }
3894
3895
3885 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3896 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3886 Name* name_raw, 3897 Name* name_raw,
3887 Object* value_raw, 3898 Object* value_raw,
3888 PropertyAttributes attributes, 3899 PropertyAttributes attributes,
3889 StrictModeFlag strict_mode, 3900 StrictModeFlag strict_mode,
3890 StoreFromKeyed store_mode) { 3901 StoreFromKeyed store_mode) {
3891 Heap* heap = GetHeap(); 3902 Heap* heap = GetHeap();
3892 Isolate* isolate = heap->isolate(); 3903 Isolate* isolate = heap->isolate();
3893 // Make sure that the top context does not change when doing callbacks or 3904 // Make sure that the top context does not change when doing callbacks or
3894 // interceptor calls. 3905 // interceptor calls.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
4098 PropertyAttributes old_attributes = ABSENT; 4109 PropertyAttributes old_attributes = ABSENT;
4099 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 4110 bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
4100 if (is_observed && lookup.IsProperty()) { 4111 if (is_observed && lookup.IsProperty()) {
4101 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); 4112 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name);
4102 old_attributes = lookup.GetAttributes(); 4113 old_attributes = lookup.GetAttributes();
4103 } 4114 }
4104 4115
4105 // Check of IsReadOnly removed from here in clone. 4116 // Check of IsReadOnly removed from here in clone.
4106 MaybeObject* result = *value; 4117 MaybeObject* result = *value;
4107 switch (lookup.type()) { 4118 switch (lookup.type()) {
4108 case NORMAL: { 4119 case NORMAL:
4109 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 4120 result = self->ReplaceSlowProperty(*name, *value, attributes);
4110 result = self->SetNormalizedProperty(*name, *value, details);
4111 break; 4121 break;
4112 }
4113 case FIELD: 4122 case FIELD:
4114 if (value->IsUninitialized()) break; 4123 result = SetPropertyToFieldWithAttributes(
4115 result = SetPropertyToField(&lookup, name, value); 4124 &lookup, name, value, attributes);
4116 break; 4125 break;
4117 case CONSTANT: 4126 case CONSTANT:
4118 // Only replace the constant if necessary. 4127 // Only replace the constant if necessary.
4119 if (*value == lookup.GetConstant()) return *value; 4128 if (lookup.GetAttributes() != attributes ||
4120 if (value->IsUninitialized()) break; 4129 *value != lookup.GetConstant()) {
4121 result = SetPropertyToField(&lookup, name, value); 4130 result = SetPropertyToFieldWithAttributes(
4131 &lookup, name, value, attributes);
4132 }
4122 break; 4133 break;
4123 case CALLBACKS: 4134 case CALLBACKS:
4135 // Callbacks are not guaranteed to be installed on the receiver. Also
4136 // perform a local lookup again. Fall through.
4124 case INTERCEPTOR: 4137 case INTERCEPTOR:
4125 // Override callback in clone 4138 self->LocalLookupRealNamedProperty(*name, &lookup);
4126 result = self->ConvertDescriptorToField(*name, *value, attributes); 4139 if (lookup.IsFound()) {
4140 if (lookup.IsPropertyCallbacks()) {
4141 result = ConvertAndSetLocalProperty(
4142 &lookup, *name, *value, attributes);
4143 } else if (lookup.IsNormal()) {
4144 result = self->ReplaceSlowProperty(*name, *value, attributes);
4145 } else {
4146 result = SetPropertyToFieldWithAttributes(
4147 &lookup, name, value, attributes);
4148 }
4149 } else {
4150 result = self->AddProperty(
4151 *name, *value, attributes, kNonStrictMode, MAY_BE_STORE_FROM_KEYED,
4152 extensibility_check, value_type, mode);
4153 }
4127 break; 4154 break;
4128 case TRANSITION: 4155 case TRANSITION:
4129 result = SetPropertyUsingTransition(&lookup, name, value, attributes); 4156 result = SetPropertyUsingTransition(&lookup, name, value, attributes);
4130 break; 4157 break;
4131 case HANDLER: 4158 case HANDLER:
4132 case NONEXISTENT: 4159 case NONEXISTENT:
4133 UNREACHABLE(); 4160 UNREACHABLE();
4134 } 4161 }
4135 4162
4136 Handle<Object> hresult; 4163 Handle<Object> hresult;
(...skipping 11845 matching lines...) Expand 10 before | Expand all | Expand 10 after
15982 #define ERROR_MESSAGES_TEXTS(C, T) T, 16009 #define ERROR_MESSAGES_TEXTS(C, T) T,
15983 static const char* error_messages_[] = { 16010 static const char* error_messages_[] = {
15984 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16011 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
15985 }; 16012 };
15986 #undef ERROR_MESSAGES_TEXTS 16013 #undef ERROR_MESSAGES_TEXTS
15987 return error_messages_[reason]; 16014 return error_messages_[reason];
15988 } 16015 }
15989 16016
15990 16017
15991 } } // namespace v8::internal 16018 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698