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

Side by Side Diff: src/objects.cc

Issue 14850006: Use mutable heapnumbers to store doubles in fields. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ported to ARM and x64 Created 7 years, 7 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 *attributes = ABSENT; 808 *attributes = ABSENT;
809 return heap->undefined_value(); 809 return heap->undefined_value();
810 } 810 }
811 *attributes = result->GetAttributes(); 811 *attributes = result->GetAttributes();
812 Object* value; 812 Object* value;
813 switch (result->type()) { 813 switch (result->type()) {
814 case NORMAL: 814 case NORMAL:
815 value = result->holder()->GetNormalizedProperty(result); 815 value = result->holder()->GetNormalizedProperty(result);
816 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 816 ASSERT(!value->IsTheHole() || result->IsReadOnly());
817 return value->IsTheHole() ? heap->undefined_value() : value; 817 return value->IsTheHole() ? heap->undefined_value() : value;
818 case FIELD: 818 case FIELD: {
819 value = result->holder()->FastPropertyAt( 819 MaybeObject* maybe_result = result->holder()->FastPropertyAt(
820 result->representation(),
820 result->GetFieldIndex().field_index()); 821 result->GetFieldIndex().field_index());
822 if (!maybe_result->To(&value)) return maybe_result;
821 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 823 ASSERT(!value->IsTheHole() || result->IsReadOnly());
822 return value->IsTheHole() ? heap->undefined_value() : value; 824 return value->IsTheHole() ? heap->undefined_value() : value;
825 }
823 case CONSTANT_FUNCTION: 826 case CONSTANT_FUNCTION:
824 return result->GetConstantFunction(); 827 return result->GetConstantFunction();
825 case CALLBACKS: 828 case CALLBACKS:
826 return result->holder()->GetPropertyWithCallback( 829 return result->holder()->GetPropertyWithCallback(
827 receiver, result->GetCallbackObject(), name); 830 receiver, result->GetCallbackObject(), name);
828 case HANDLER: 831 case HANDLER:
829 return result->proxy()->GetPropertyWithHandler(receiver, name); 832 return result->proxy()->GetPropertyWithHandler(receiver, name);
830 case INTERCEPTOR: 833 case INTERCEPTOR:
831 return result->holder()->GetPropertyWithInterceptor( 834 return result->holder()->GetPropertyWithInterceptor(
832 receiver, name, attributes); 835 receiver, name, attributes);
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 } 1707 }
1705 // TODO(rossberg): what about proxies? 1708 // TODO(rossberg): what about proxies?
1706 // If the constructor is not present, return "Object". 1709 // If the constructor is not present, return "Object".
1707 return GetHeap()->Object_string(); 1710 return GetHeap()->Object_string();
1708 } 1711 }
1709 1712
1710 1713
1711 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1714 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1712 Name* name, 1715 Name* name,
1713 Object* value, 1716 Object* value,
1714 int field_index) { 1717 int field_index,
1718 Representation representation) {
1719 // This method is used to transition to a field. If we are transitioning to a
1720 // double field, allocate new storage.
1721 Object* storage;
1722 MaybeObject* maybe_storage =
1723 value->AllocateNewStorageFor(GetHeap(), representation);
1724 if (!maybe_storage->To(&storage)) return maybe_storage;
1725
1715 if (map()->unused_property_fields() == 0) { 1726 if (map()->unused_property_fields() == 0) {
1716 int new_unused = new_map->unused_property_fields(); 1727 int new_unused = new_map->unused_property_fields();
1717 FixedArray* values; 1728 FixedArray* values;
1718 MaybeObject* maybe_values = 1729 MaybeObject* maybe_values =
1719 properties()->CopySize(properties()->length() + new_unused + 1); 1730 properties()->CopySize(properties()->length() + new_unused + 1);
1720 if (!maybe_values->To(&values)) return maybe_values; 1731 if (!maybe_values->To(&values)) return maybe_values;
1721 1732
1722 set_properties(values); 1733 set_properties(values);
1723 } 1734 }
1735
1724 set_map(new_map); 1736 set_map(new_map);
1725 return FastPropertyAtPut(field_index, value); 1737
1738 FastPropertyAtPut(field_index, storage);
1739 return value;
1726 } 1740 }
1727 1741
1728 1742
1729 static bool IsIdentifier(UnicodeCache* cache, Name* name) { 1743 static bool IsIdentifier(UnicodeCache* cache, Name* name) {
1730 // Checks whether the buffer contains an identifier (no escape). 1744 // Checks whether the buffer contains an identifier (no escape).
1731 if (!name->IsString()) return false; 1745 if (!name->IsString()) return false;
1732 String* string = String::cast(name); 1746 String* string = String::cast(name);
1733 if (string->length() == 0) return false; 1747 if (string->length() == 0) return false;
1734 ConsStringIteratorOp op; 1748 ConsStringIteratorOp op;
1735 StringCharacterStream stream(string, &op); 1749 StringCharacterStream stream(string, &op);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1781 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1768 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1782 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1769 1783
1770 return AddSlowProperty(name, value, attributes); 1784 return AddSlowProperty(name, value, attributes);
1771 } 1785 }
1772 1786
1773 // Compute the new index for new field. 1787 // Compute the new index for new field.
1774 int index = map()->NextFreePropertyIndex(); 1788 int index = map()->NextFreePropertyIndex();
1775 1789
1776 // Allocate new instance descriptors with (name, index) added 1790 // Allocate new instance descriptors with (name, index) added
1777 FieldDescriptor new_field( 1791 Representation representation = value->OptimalRepresentation();
1778 name, index, attributes, value->OptimalRepresentation(), 0); 1792 FieldDescriptor new_field(name, index, attributes, representation, 0);
1779 1793
1780 ASSERT(index < map()->inobject_properties() || 1794 ASSERT(index < map()->inobject_properties() ||
1781 (index - map()->inobject_properties()) < properties()->length() || 1795 (index - map()->inobject_properties()) < properties()->length() ||
1782 map()->unused_property_fields() == 0); 1796 map()->unused_property_fields() == 0);
1783 1797
1784 FixedArray* values = NULL; 1798 FixedArray* values = NULL;
1785 1799
1800 // TODO(verwaest): Merge with AddFastPropertyUsingMap.
1786 if (map()->unused_property_fields() == 0) { 1801 if (map()->unused_property_fields() == 0) {
1787 // Make room for the new value 1802 // Make room for the new value
1788 MaybeObject* maybe_values = 1803 MaybeObject* maybe_values =
1789 properties()->CopySize(properties()->length() + kFieldsAdded); 1804 properties()->CopySize(properties()->length() + kFieldsAdded);
1790 if (!maybe_values->To(&values)) return maybe_values; 1805 if (!maybe_values->To(&values)) return maybe_values;
1791 } 1806 }
1792 1807
1793 TransitionFlag flag = INSERT_TRANSITION; 1808 TransitionFlag flag = INSERT_TRANSITION;
1794 1809
1810 Heap* heap = isolate->heap();
1811
1795 Map* new_map; 1812 Map* new_map;
1796 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); 1813 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
1797 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 1814 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
1798 1815
1816 Object* storage;
1817 MaybeObject* maybe_storage =
1818 value->AllocateNewStorageFor(heap, representation);
1819 if (!maybe_storage->To(&storage)) return maybe_storage;
1820
1799 if (map()->unused_property_fields() == 0) { 1821 if (map()->unused_property_fields() == 0) {
1800 ASSERT(values != NULL); 1822 ASSERT(values != NULL);
1801 set_properties(values); 1823 set_properties(values);
1802 new_map->set_unused_property_fields(kFieldsAdded - 1); 1824 new_map->set_unused_property_fields(kFieldsAdded - 1);
1803 } else { 1825 } else {
1804 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); 1826 new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
1805 } 1827 }
1806 1828
1807 set_map(new_map); 1829 set_map(new_map);
1808 return FastPropertyAtPut(index, value); 1830
1831 FastPropertyAtPut(index, storage);
1832 return value;
1809 } 1833 }
1810 1834
1811 1835
1812 MaybeObject* JSObject::AddConstantFunctionProperty( 1836 MaybeObject* JSObject::AddConstantFunctionProperty(
1813 Name* name, 1837 Name* name,
1814 JSFunction* function, 1838 JSFunction* function,
1815 PropertyAttributes attributes) { 1839 PropertyAttributes attributes) {
1816 // Allocate new instance descriptors with (name, function) added 1840 // Allocate new instance descriptors with (name, function) added
1817 ConstantFunctionDescriptor d(name, function, attributes, 0); 1841 ConstantFunctionDescriptor d(name, function, attributes, 0);
1818 1842
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 Object* new_value, 2088 Object* new_value,
2065 PropertyAttributes attributes) { 2089 PropertyAttributes attributes) {
2066 if (map()->unused_property_fields() == 0 && 2090 if (map()->unused_property_fields() == 0 &&
2067 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { 2091 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
2068 Object* obj; 2092 Object* obj;
2069 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2093 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2070 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2094 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2071 return ReplaceSlowProperty(name, new_value, attributes); 2095 return ReplaceSlowProperty(name, new_value, attributes);
2072 } 2096 }
2073 2097
2098 Representation representation = new_value->OptimalRepresentation();
2074 int index = map()->NextFreePropertyIndex(); 2099 int index = map()->NextFreePropertyIndex();
2075 FieldDescriptor new_field( 2100 FieldDescriptor new_field(name, index, attributes, representation, 0);
2076 name, index, attributes, new_value->OptimalRepresentation(), 0);
2077 2101
2078 // Make a new map for the object. 2102 // Make a new map for the object.
2079 Map* new_map; 2103 Map* new_map;
2080 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, 2104 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field,
2081 OMIT_TRANSITION); 2105 OMIT_TRANSITION);
2082 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2106 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2083 2107
2084 // Make new properties array if necessary. 2108 // Make new properties array if necessary.
2085 FixedArray* new_properties = NULL; 2109 FixedArray* new_properties = NULL;
2086 int new_unused_property_fields = map()->unused_property_fields() - 1; 2110 int new_unused_property_fields = map()->unused_property_fields() - 1;
2087 if (map()->unused_property_fields() == 0) { 2111 if (map()->unused_property_fields() == 0) {
2088 new_unused_property_fields = kFieldsAdded - 1; 2112 new_unused_property_fields = kFieldsAdded - 1;
2089 MaybeObject* maybe_new_properties = 2113 MaybeObject* maybe_new_properties =
2090 properties()->CopySize(properties()->length() + kFieldsAdded); 2114 properties()->CopySize(properties()->length() + kFieldsAdded);
2091 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties; 2115 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties;
2092 } 2116 }
2093 2117
2118 Heap* heap = GetHeap();
2119 Object* storage;
2120 MaybeObject* maybe_storage =
2121 new_value->AllocateNewStorageFor(heap, representation);
2122 if (!maybe_storage->To(&storage)) return maybe_storage;
2123
2094 // Update pointers to commit changes. 2124 // Update pointers to commit changes.
2095 // Object points to the new map. 2125 // Object points to the new map.
2096 new_map->set_unused_property_fields(new_unused_property_fields); 2126 new_map->set_unused_property_fields(new_unused_property_fields);
2097 set_map(new_map); 2127 set_map(new_map);
2098 if (new_properties != NULL) { 2128 if (new_properties != NULL) {
2099 set_properties(new_properties); 2129 set_properties(new_properties);
2100 } 2130 }
2101 return FastPropertyAtPut(index, new_value); 2131 FastPropertyAtPut(index, new_value);
2132 return new_value;
2102 } 2133 }
2103 2134
2104 2135
2105 const char* Representation::Mnemonic() const { 2136 const char* Representation::Mnemonic() const {
2106 switch (kind_) { 2137 switch (kind_) {
2107 case kNone: return "v"; 2138 case kNone: return "v";
2108 case kTagged: return "t"; 2139 case kTagged: return "t";
2109 case kSmi: return "s"; 2140 case kSmi: return "s";
2110 case kDouble: return "d"; 2141 case kDouble: return "d";
2111 case kInteger32: return "i"; 2142 case kInteger32: return "i";
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) { 2190 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
2160 if (trim_mode == FROM_GC) { 2191 if (trim_mode == FROM_GC) {
2161 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta); 2192 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
2162 } else { 2193 } else {
2163 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta); 2194 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2164 } 2195 }
2165 } 2196 }
2166 } 2197 }
2167 2198
2168 2199
2169 bool Map::InstancesNeedRewriting(int target_number_of_fields, 2200 bool Map::InstancesNeedRewriting(Map* target,
2201 int target_number_of_fields,
2170 int target_inobject, 2202 int target_inobject,
2171 int target_unused) { 2203 int target_unused) {
2172 // If fields were added (or removed), rewrite the instance. 2204 // If fields were added (or removed), rewrite the instance.
2173 int number_of_fields = NumberOfFields(); 2205 int number_of_fields = NumberOfFields();
2174 ASSERT(target_number_of_fields >= number_of_fields); 2206 ASSERT(target_number_of_fields >= number_of_fields);
2175 if (target_number_of_fields != number_of_fields) return true; 2207 if (target_number_of_fields != number_of_fields) return true;
2208
2209 if (FLAG_track_double_fields) {
2210 // If smi descriptors were replaced by double descriptors, rewrite.
2211 DescriptorArray* old_desc = instance_descriptors();
2212 DescriptorArray* new_desc = target->instance_descriptors();
2213 int limit = NumberOfOwnDescriptors();
2214 for (int i = 0; i < limit; i++) {
2215 if (new_desc->GetDetails(i).representation().IsDouble() &&
2216 old_desc->GetDetails(i).representation().IsSmi()) {
2217 return true;
2218 }
2219 }
2220 }
2221
2176 // If no fields were added, and no inobject properties were removed, setting 2222 // If no fields were added, and no inobject properties were removed, setting
2177 // the map is sufficient. 2223 // the map is sufficient.
2178 if (target_inobject == inobject_properties()) return false; 2224 if (target_inobject == inobject_properties()) return false;
2179 // In-object slack tracking may have reduced the object size of the new map. 2225 // In-object slack tracking may have reduced the object size of the new map.
2180 // In that case, succeed if all existing fields were inobject, and they still 2226 // In that case, succeed if all existing fields were inobject, and they still
2181 // fit within the new inobject size. 2227 // fit within the new inobject size.
2182 ASSERT(target_inobject < inobject_properties()); 2228 ASSERT(target_inobject < inobject_properties());
2183 if (target_number_of_fields <= target_inobject) { 2229 if (target_number_of_fields <= target_inobject) {
2184 ASSERT(target_number_of_fields + target_unused == target_inobject); 2230 ASSERT(target_number_of_fields + target_unused == target_inobject);
2185 return false; 2231 return false;
(...skipping 19 matching lines...) Expand all
2205 // * If there are properties left in the backing store, install the backing 2251 // * If there are properties left in the backing store, install the backing
2206 // store. 2252 // store.
2207 MaybeObject* JSObject::MigrateToMap(Map* new_map) { 2253 MaybeObject* JSObject::MigrateToMap(Map* new_map) {
2208 Heap* heap = GetHeap(); 2254 Heap* heap = GetHeap();
2209 Map* old_map = map(); 2255 Map* old_map = map();
2210 int number_of_fields = new_map->NumberOfFields(); 2256 int number_of_fields = new_map->NumberOfFields();
2211 int inobject = new_map->inobject_properties(); 2257 int inobject = new_map->inobject_properties();
2212 int unused = new_map->unused_property_fields(); 2258 int unused = new_map->unused_property_fields();
2213 2259
2214 // Nothing to do if no functions were converted to fields. 2260 // Nothing to do if no functions were converted to fields.
2215 if (!old_map->InstancesNeedRewriting(number_of_fields, inobject, unused)) { 2261 if (!old_map->InstancesNeedRewriting(
2262 new_map, number_of_fields, inobject, unused)) {
2216 set_map(new_map); 2263 set_map(new_map);
2217 return this; 2264 return this;
2218 } 2265 }
2219 2266
2220 int total_size = number_of_fields + unused; 2267 int total_size = number_of_fields + unused;
2221 int external = total_size - inobject; 2268 int external = total_size - inobject;
2222 FixedArray* array; 2269 FixedArray* array;
2223 MaybeObject* maybe_array = heap->AllocateFixedArray(total_size); 2270 MaybeObject* maybe_array = heap->AllocateFixedArray(total_size);
2224 if (!maybe_array->To(&array)) return maybe_array; 2271 if (!maybe_array->To(&array)) return maybe_array;
2225 2272
2226 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2273 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2227 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2274 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2228 int descriptors = new_map->NumberOfOwnDescriptors(); 2275 int descriptors = new_map->NumberOfOwnDescriptors();
2229 2276
2230 for (int i = 0; i < descriptors; i++) { 2277 for (int i = 0; i < descriptors; i++) {
2231 PropertyDetails details = new_descriptors->GetDetails(i); 2278 PropertyDetails details = new_descriptors->GetDetails(i);
2232 if (details.type() != FIELD) continue; 2279 if (details.type() != FIELD) continue;
2233 PropertyDetails old_details = old_descriptors->GetDetails(i); 2280 PropertyDetails old_details = old_descriptors->GetDetails(i);
2234 ASSERT(old_details.type() == CONSTANT_FUNCTION || 2281 ASSERT(old_details.type() == CONSTANT_FUNCTION ||
2235 old_details.type() == FIELD); 2282 old_details.type() == FIELD);
2236 Object* value = old_details.type() == CONSTANT_FUNCTION 2283 Object* value = old_details.type() == CONSTANT_FUNCTION
2237 ? old_descriptors->GetValue(i) 2284 ? old_descriptors->GetValue(i)
2238 : FastPropertyAt(old_descriptors->GetFieldIndex(i)); 2285 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2286 if (FLAG_track_double_fields &&
2287 old_details.representation().IsSmi() &&
2288 details.representation().IsDouble()) {
2289 // Objects must be allocated in the old object space, since the
2290 // overall number of HeapNumbers needed for the conversion might
2291 // exceed the capacity of new space, and we would fail repeatedly
2292 // trying to migrate the instance.
2293 MaybeObject* maybe_storage =
2294 value->AllocateNewStorageFor(heap, details.representation(), TENURED);
2295 if (!maybe_storage->To(&value)) return maybe_storage;
2296 }
2297 ASSERT(!(FLAG_track_double_fields &&
2298 details.representation().IsDouble() &&
2299 value->IsSmi()));
2239 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2300 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2240 if (target_index < 0) target_index += total_size; 2301 if (target_index < 0) target_index += total_size;
2241 array->set(target_index, value); 2302 array->set(target_index, value);
2242 } 2303 }
2243 2304
2244 // From here on we cannot fail anymore. 2305 // From here on we cannot fail anymore.
2245 2306
2246 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2307 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2247 // avoid overwriting |one_pointer_filler_map|. 2308 // avoid overwriting |one_pointer_filler_map|.
2248 int limit = Min(inobject, number_of_fields); 2309 int limit = Min(inobject, number_of_fields);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 } 2354 }
2294 2355
2295 2356
2296 MaybeObject* Map::CopyGeneralizeAllRepresentations() { 2357 MaybeObject* Map::CopyGeneralizeAllRepresentations() {
2297 Map* new_map; 2358 Map* new_map;
2298 MaybeObject* maybe_map = this->Copy(); 2359 MaybeObject* maybe_map = this->Copy();
2299 if (!maybe_map->To(&new_map)) return maybe_map; 2360 if (!maybe_map->To(&new_map)) return maybe_map;
2300 2361
2301 new_map->instance_descriptors()->InitializeRepresentations( 2362 new_map->instance_descriptors()->InitializeRepresentations(
2302 Representation::Tagged()); 2363 Representation::Tagged());
2364 if (FLAG_trace_generalization) {
2365 PrintF("failed generalization %p -> %p\n",
2366 static_cast<void*>(this), static_cast<void*>(new_map));
2367 }
2303 return new_map; 2368 return new_map;
2304 } 2369 }
2305 2370
2306 2371
2307 void Map::DeprecateTransitionTree() { 2372 void Map::DeprecateTransitionTree() {
2308 if (!FLAG_track_fields) return; 2373 if (!FLAG_track_fields) return;
2309 if (is_deprecated()) return; 2374 if (is_deprecated()) return;
2310 if (HasTransitionArray()) { 2375 if (HasTransitionArray()) {
2311 TransitionArray* transitions = this->transitions(); 2376 TransitionArray* transitions = this->transitions();
2312 for (int i = 0; i < transitions->number_of_transitions(); i++) { 2377 for (int i = 0; i < transitions->number_of_transitions(); i++) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 Map* updated = root_map->FindUpdatedMap( 2523 Map* updated = root_map->FindUpdatedMap(
2459 verbatim, descriptors, old_descriptors); 2524 verbatim, descriptors, old_descriptors);
2460 // Check the state of the root map. 2525 // Check the state of the root map.
2461 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2526 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2462 2527
2463 int valid = updated->NumberOfOwnDescriptors(); 2528 int valid = updated->NumberOfOwnDescriptors();
2464 if (updated_descriptors->IsMoreGeneralThan( 2529 if (updated_descriptors->IsMoreGeneralThan(
2465 verbatim, valid, descriptors, old_descriptors)) { 2530 verbatim, valid, descriptors, old_descriptors)) {
2466 Representation updated_representation = 2531 Representation updated_representation =
2467 updated_descriptors->GetDetails(modify_index).representation(); 2532 updated_descriptors->GetDetails(modify_index).representation();
2468 if (new_representation.fits_into(updated_representation)) return updated; 2533 if (new_representation.fits_into(updated_representation)) {
2534 if (FLAG_trace_generalization) {
2535 PrintF("migrating to existing map %p -> %p\n",
2536 static_cast<void*>(this), static_cast<void*>(updated));
2537 }
2538 return updated;
2539 }
2469 } 2540 }
2470 2541
2471 DescriptorArray* new_descriptors; 2542 DescriptorArray* new_descriptors;
2472 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2543 MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2473 verbatim, valid, descriptors, old_descriptors); 2544 verbatim, valid, descriptors, old_descriptors);
2474 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 2545 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2475 2546
2476 old_reprepresentation = 2547 old_reprepresentation =
2477 new_descriptors->GetDetails(modify_index).representation(); 2548 new_descriptors->GetDetails(modify_index).representation();
2478 new_representation = new_representation.generalize(old_reprepresentation); 2549 new_representation = new_representation.generalize(old_reprepresentation);
2479 new_descriptors->SetRepresentation(modify_index, new_representation); 2550 new_descriptors->SetRepresentation(modify_index, new_representation);
2480 2551
2481 Map* split_map = root_map->FindLastMatchMap( 2552 Map* split_map = root_map->FindLastMatchMap(
2482 verbatim, descriptors, new_descriptors); 2553 verbatim, descriptors, new_descriptors);
2483 2554
2484 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2555 int split_descriptors = split_map->NumberOfOwnDescriptors();
2485 // This is shadowed by |updated_descriptors| being more general than 2556 // This is shadowed by |updated_descriptors| being more general than
2486 // |old_descriptors|. 2557 // |old_descriptors|.
2487 ASSERT(descriptors != split_descriptors); 2558 ASSERT(descriptors != split_descriptors);
2488 2559
2489 int descriptor = split_descriptors; 2560 int descriptor = split_descriptors;
2490 split_map->DeprecateTarget( 2561 split_map->DeprecateTarget(
2491 old_descriptors->GetKey(descriptor), new_descriptors); 2562 old_descriptors->GetKey(descriptor), new_descriptors);
2492 2563
2564 if (FLAG_trace_generalization) {
2565 PrintF("migrating to new map %p -> %p (%i steps)\n",
2566 static_cast<void*>(this),
2567 static_cast<void*>(new_descriptors),
2568 descriptors - descriptor);
2569 }
2570
2493 Map* new_map = split_map; 2571 Map* new_map = split_map;
2494 // Add missing transitions. 2572 // Add missing transitions.
2495 for (; descriptor < descriptors; descriptor++) { 2573 for (; descriptor < descriptors; descriptor++) {
2496 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2574 MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2497 descriptor, new_descriptors); 2575 descriptor, new_descriptors);
2498 if (!maybe_map->To(&new_map)) { 2576 if (!maybe_map->To(&new_map)) {
2499 // Create a handle for the last created map to ensure it stays alive 2577 // Create a handle for the last created map to ensure it stays alive
2500 // during GC. Its descriptor array is too large, but it will be 2578 // during GC. Its descriptor array is too large, but it will be
2501 // overwritten during retry anyway. 2579 // overwritten during retry anyway.
2502 Handle<Map>(new_map); 2580 Handle<Map>(new_map);
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
3025 map()->LookupDescriptor(this, name, result); 3103 map()->LookupDescriptor(this, name, result);
3026 // A property or a map transition was found. We return all of these result 3104 // A property or a map transition was found. We return all of these result
3027 // types because LocalLookupRealNamedProperty is used when setting 3105 // types because LocalLookupRealNamedProperty is used when setting
3028 // properties where map transitions are handled. 3106 // properties where map transitions are handled.
3029 ASSERT(!result->IsFound() || 3107 ASSERT(!result->IsFound() ||
3030 (result->holder() == this && result->IsFastPropertyType())); 3108 (result->holder() == this && result->IsFastPropertyType()));
3031 // Disallow caching for uninitialized constants. These can only 3109 // Disallow caching for uninitialized constants. These can only
3032 // occur as fields. 3110 // occur as fields.
3033 if (result->IsField() && 3111 if (result->IsField() &&
3034 result->IsReadOnly() && 3112 result->IsReadOnly() &&
3035 FastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) { 3113 RawFastPropertyAt(result->GetFieldIndex().field_index())->IsTheHole()) {
3036 result->DisallowCaching(); 3114 result->DisallowCaching();
3037 } 3115 }
3038 return; 3116 return;
3039 } 3117 }
3040 3118
3041 int entry = property_dictionary()->FindEntry(name); 3119 int entry = property_dictionary()->FindEntry(name);
3042 if (entry != NameDictionary::kNotFound) { 3120 if (entry != NameDictionary::kNotFound) {
3043 Object* value = property_dictionary()->ValueAt(entry); 3121 Object* value = property_dictionary()->ValueAt(entry);
3044 if (IsGlobalObject()) { 3122 if (IsGlobalObject()) {
3045 PropertyDetails d = property_dictionary()->DetailsAt(entry); 3123 PropertyDetails d = property_dictionary()->DetailsAt(entry);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 return Handle<Object>(); 3536 return Handle<Object>();
3459 } 3537 }
3460 trap = Handle<Object>(derived); 3538 trap = Handle<Object>(derived);
3461 } 3539 }
3462 3540
3463 bool threw; 3541 bool threw;
3464 return Execution::Call(trap, handler, argc, argv, &threw); 3542 return Execution::Call(trap, handler, argc, argv, &threw);
3465 } 3543 }
3466 3544
3467 3545
3468 void JSObject::TransitionToMap(Handle<JSObject> object, Handle<Map> map) { 3546 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3469 CALL_HEAP_FUNCTION_VOID( 3547 CALL_HEAP_FUNCTION_VOID(
3470 object->GetIsolate(), 3548 object->GetIsolate(),
3471 object->TransitionToMap(*map)); 3549 object->AllocateStorageForMap(*map));
3472 } 3550 }
3473 3551
3474 3552
3475 void JSObject::MigrateInstance(Handle<JSObject> object) { 3553 void JSObject::MigrateInstance(Handle<JSObject> object) {
3554 if (FLAG_trace_migration) {
3555 PrintF("migrating instance %p (%p)\n",
3556 static_cast<void*>(*object),
3557 static_cast<void*>(object->map()));
3558 }
3476 CALL_HEAP_FUNCTION_VOID( 3559 CALL_HEAP_FUNCTION_VOID(
3477 object->GetIsolate(), 3560 object->GetIsolate(),
3478 object->MigrateInstance()); 3561 object->MigrateInstance());
3479 } 3562 }
3480 3563
3481 3564
3482 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3565 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
3483 int modify_index, 3566 int modify_index,
3484 Representation new_representation) { 3567 Representation representation) {
3485 CALL_HEAP_FUNCTION( 3568 CALL_HEAP_FUNCTION(
3486 map->GetIsolate(), 3569 map->GetIsolate(),
3487 map->GeneralizeRepresentation(modify_index, new_representation), 3570 map->GeneralizeRepresentation(modify_index, representation),
3488 Map); 3571 Map);
3489 } 3572 }
3490 3573
3491 3574
3492 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3575 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3493 Name* name_raw, 3576 Name* name_raw,
3494 Object* value_raw, 3577 Object* value_raw,
3495 PropertyAttributes attributes, 3578 PropertyAttributes attributes,
3496 StrictModeFlag strict_mode, 3579 StrictModeFlag strict_mode,
3497 StoreFromKeyed store_mode) { 3580 StoreFromKeyed store_mode) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3577 case NORMAL: 3660 case NORMAL:
3578 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3661 result = lookup->holder()->SetNormalizedProperty(lookup, *value);
3579 break; 3662 break;
3580 case FIELD: { 3663 case FIELD: {
3581 Representation representation = lookup->representation(); 3664 Representation representation = lookup->representation();
3582 if (!value->FitsRepresentation(representation)) { 3665 if (!value->FitsRepresentation(representation)) {
3583 MaybeObject* maybe_failure = 3666 MaybeObject* maybe_failure =
3584 lookup->holder()->GeneralizeFieldRepresentation( 3667 lookup->holder()->GeneralizeFieldRepresentation(
3585 lookup->GetDescriptorIndex(), value->OptimalRepresentation()); 3668 lookup->GetDescriptorIndex(), value->OptimalRepresentation());
3586 if (maybe_failure->IsFailure()) return maybe_failure; 3669 if (maybe_failure->IsFailure()) return maybe_failure;
3670 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3671 int descriptor = lookup->GetDescriptorIndex();
3672 representation = desc->GetDetails(descriptor).representation();
3587 } 3673 }
3588 result = lookup->holder()->FastPropertyAtPut( 3674 if (FLAG_track_double_fields && representation.IsDouble()) {
3675 HeapNumber* storage =
3676 HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3677 lookup->GetFieldIndex().field_index()));
3678 storage->set_value(value->Number());
3679 result = *value;
3680 break;
3681 }
3682 lookup->holder()->FastPropertyAtPut(
3589 lookup->GetFieldIndex().field_index(), *value); 3683 lookup->GetFieldIndex().field_index(), *value);
3684 result = *value;
3590 break; 3685 break;
3591 } 3686 }
3592 case CONSTANT_FUNCTION: 3687 case CONSTANT_FUNCTION:
3593 // Only replace the function if necessary. 3688 // Only replace the function if necessary.
3594 if (*value == lookup->GetConstantFunction()) return *value; 3689 if (*value == lookup->GetConstantFunction()) return *value;
3595 // Preserve the attributes of this existing property. 3690 // Preserve the attributes of this existing property.
3596 attributes = lookup->GetAttributes(); 3691 attributes = lookup->GetAttributes();
3597 result = 3692 result =
3598 lookup->holder()->ConvertDescriptorToField(*name, *value, attributes); 3693 lookup->holder()->ConvertDescriptorToField(*name, *value, attributes);
3599 break; 3694 break;
3600 case CALLBACKS: { 3695 case CALLBACKS: {
3601 Object* callback_object = lookup->GetCallbackObject(); 3696 Object* callback_object = lookup->GetCallbackObject();
3602 return self->SetPropertyWithCallback( 3697 return self->SetPropertyWithCallback(
3603 callback_object, *name, *value, lookup->holder(), strict_mode); 3698 callback_object, *name, *value, lookup->holder(), strict_mode);
3604 } 3699 }
3605 case INTERCEPTOR: 3700 case INTERCEPTOR:
3606 result = lookup->holder()->SetPropertyWithInterceptor( 3701 result = lookup->holder()->SetPropertyWithInterceptor(
3607 *name, *value, attributes, strict_mode); 3702 *name, *value, attributes, strict_mode);
3608 break; 3703 break;
3609 case TRANSITION: { 3704 case TRANSITION: {
3610 Map* transition_map = lookup->GetTransitionTarget(); 3705 Map* transition_map = lookup->GetTransitionTarget();
3611 int descriptor = transition_map->LastAdded(); 3706 int descriptor = transition_map->LastAdded();
3612 3707
3613 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3708 DescriptorArray* descriptors = transition_map->instance_descriptors();
3614 PropertyDetails details = descriptors->GetDetails(descriptor); 3709 PropertyDetails details = descriptors->GetDetails(descriptor);
3615 3710
3616 if (details.type() == FIELD) { 3711 if (details.type() == FIELD) {
3617 if (attributes == details.attributes()) { 3712 if (attributes == details.attributes()) {
3618 if (!value->FitsRepresentation(details.representation())) { 3713 Representation representation = details.representation();
3714 if (!value->FitsRepresentation(representation)) {
3619 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3715 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3620 descriptor, value->OptimalRepresentation()); 3716 descriptor, value->OptimalRepresentation());
3621 if (!maybe_map->To(&transition_map)) return maybe_map; 3717 if (!maybe_map->To(&transition_map)) return maybe_map;
3622 Object* back = transition_map->GetBackPointer(); 3718 Object* back = transition_map->GetBackPointer();
3623 if (back->IsMap()) { 3719 if (back->IsMap()) {
3624 MaybeObject* maybe_failure = 3720 MaybeObject* maybe_failure =
3625 lookup->holder()->MigrateToMap(Map::cast(back)); 3721 lookup->holder()->MigrateToMap(Map::cast(back));
3626 if (maybe_failure->IsFailure()) return maybe_failure; 3722 if (maybe_failure->IsFailure()) return maybe_failure;
3627 } 3723 }
3724 DescriptorArray* desc = transition_map->instance_descriptors();
3725 int descriptor = transition_map->LastAdded();
3726 representation = desc->GetDetails(descriptor).representation();
3628 } 3727 }
3629 int field_index = descriptors->GetFieldIndex(descriptor); 3728 int field_index = descriptors->GetFieldIndex(descriptor);
3630 result = lookup->holder()->AddFastPropertyUsingMap( 3729 result = lookup->holder()->AddFastPropertyUsingMap(
3631 transition_map, *name, *value, field_index); 3730 transition_map, *name, *value, field_index, representation);
3632 } else { 3731 } else {
3633 result = lookup->holder()->ConvertDescriptorToField( 3732 result = lookup->holder()->ConvertDescriptorToField(
3634 *name, *value, attributes); 3733 *name, *value, attributes);
3635 } 3734 }
3636 } else if (details.type() == CALLBACKS) { 3735 } else if (details.type() == CALLBACKS) {
3637 result = lookup->holder()->ConvertDescriptorToField( 3736 result = lookup->holder()->ConvertDescriptorToField(
3638 *name, *value, attributes); 3737 *name, *value, attributes);
3639 } else { 3738 } else {
3640 ASSERT(details.type() == CONSTANT_FUNCTION); 3739 ASSERT(details.type() == CONSTANT_FUNCTION);
3641 3740
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3762 attributes, NORMAL, Representation::None()); 3861 attributes, NORMAL, Representation::None());
3763 result = self->SetNormalizedProperty(*name, *value, details); 3862 result = self->SetNormalizedProperty(*name, *value, details);
3764 break; 3863 break;
3765 } 3864 }
3766 case FIELD: { 3865 case FIELD: {
3767 Representation representation = lookup.representation(); 3866 Representation representation = lookup.representation();
3768 if (!value->FitsRepresentation(representation)) { 3867 if (!value->FitsRepresentation(representation)) {
3769 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( 3868 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation(
3770 lookup.GetDescriptorIndex(), value->OptimalRepresentation()); 3869 lookup.GetDescriptorIndex(), value->OptimalRepresentation());
3771 if (maybe_failure->IsFailure()) return maybe_failure; 3870 if (maybe_failure->IsFailure()) return maybe_failure;
3871 DescriptorArray* desc = self->map()->instance_descriptors();
3872 int descriptor = lookup.GetDescriptorIndex();
3873 representation = desc->GetDetails(descriptor).representation();
3772 } 3874 }
3773 result = self->FastPropertyAtPut( 3875 if (FLAG_track_double_fields && representation.IsDouble()) {
3774 lookup.GetFieldIndex().field_index(), *value); 3876 HeapNumber* storage =
3877 HeapNumber::cast(self->RawFastPropertyAt(
3878 lookup.GetFieldIndex().field_index()));
3879 storage->set_value(value->Number());
3880 result = *value;
3881 break;
3882 }
3883 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value);
3884 result = *value;
3775 break; 3885 break;
3776 } 3886 }
3777 case CONSTANT_FUNCTION: 3887 case CONSTANT_FUNCTION:
3778 // Only replace the function if necessary. 3888 // Only replace the function if necessary.
3779 if (*value != lookup.GetConstantFunction()) { 3889 if (*value != lookup.GetConstantFunction()) {
3780 // Preserve the attributes of this existing property. 3890 // Preserve the attributes of this existing property.
3781 attributes = lookup.GetAttributes(); 3891 attributes = lookup.GetAttributes();
3782 result = self->ConvertDescriptorToField(*name, *value, attributes); 3892 result = self->ConvertDescriptorToField(*name, *value, attributes);
3783 } 3893 }
3784 break; 3894 break;
3785 case CALLBACKS: 3895 case CALLBACKS:
3786 case INTERCEPTOR: 3896 case INTERCEPTOR:
3787 // Override callback in clone 3897 // Override callback in clone
3788 result = self->ConvertDescriptorToField(*name, *value, attributes); 3898 result = self->ConvertDescriptorToField(*name, *value, attributes);
3789 break; 3899 break;
3790 case TRANSITION: { 3900 case TRANSITION: {
3791 Map* transition_map = lookup.GetTransitionTarget(); 3901 Map* transition_map = lookup.GetTransitionTarget();
3792 int descriptor = transition_map->LastAdded(); 3902 int descriptor = transition_map->LastAdded();
3793 3903
3794 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3904 DescriptorArray* descriptors = transition_map->instance_descriptors();
3795 PropertyDetails details = descriptors->GetDetails(descriptor); 3905 PropertyDetails details = descriptors->GetDetails(descriptor);
3796 3906
3797 if (details.type() == FIELD) { 3907 if (details.type() == FIELD) {
3798 if (attributes == details.attributes()) { 3908 if (attributes == details.attributes()) {
3799 if (!value->FitsRepresentation(details.representation())) { 3909 Representation representation = details.representation();
3910 if (!value->FitsRepresentation(representation)) {
3800 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3911 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3801 descriptor, value->OptimalRepresentation()); 3912 descriptor, value->OptimalRepresentation());
3802 if (!maybe_map->To(&transition_map)) return maybe_map; 3913 if (!maybe_map->To(&transition_map)) return maybe_map;
3803 Object* back = transition_map->GetBackPointer(); 3914 Object* back = transition_map->GetBackPointer();
3804 if (back->IsMap()) { 3915 if (back->IsMap()) {
3805 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back)); 3916 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back));
3806 if (maybe_failure->IsFailure()) return maybe_failure; 3917 if (maybe_failure->IsFailure()) return maybe_failure;
3807 } 3918 }
3919 DescriptorArray* desc = transition_map->instance_descriptors();
3920 int descriptor = transition_map->LastAdded();
3921 representation = desc->GetDetails(descriptor).representation();
3808 } 3922 }
3809 int field_index = descriptors->GetFieldIndex(descriptor); 3923 int field_index = descriptors->GetFieldIndex(descriptor);
3810 result = self->AddFastPropertyUsingMap( 3924 result = self->AddFastPropertyUsingMap(
3811 transition_map, *name, *value, field_index); 3925 transition_map, *name, *value, field_index, representation);
3812 } else { 3926 } else {
3813 result = self->ConvertDescriptorToField(*name, *value, attributes); 3927 result = self->ConvertDescriptorToField(*name, *value, attributes);
3814 } 3928 }
3815 } else if (details.type() == CALLBACKS) { 3929 } else if (details.type() == CALLBACKS) {
3816 result = self->ConvertDescriptorToField(*name, *value, attributes); 3930 result = self->ConvertDescriptorToField(*name, *value, attributes);
3817 } else { 3931 } else {
3818 ASSERT(details.type() == CONSTANT_FUNCTION); 3932 ASSERT(details.type() == CONSTANT_FUNCTION);
3819 3933
3820 // Replace transition to CONSTANT FUNCTION with a map transition to a 3934 // Replace transition to CONSTANT FUNCTION with a map transition to a
3821 // new map with a FIELD, even if the value is a function. 3935 // new map with a FIELD, even if the value is a function.
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
4226 MaybeObject* maybe_dictionary = 4340 MaybeObject* maybe_dictionary =
4227 dictionary->Add(descs->GetKey(i), value, d); 4341 dictionary->Add(descs->GetKey(i), value, d);
4228 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 4342 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
4229 break; 4343 break;
4230 } 4344 }
4231 case FIELD: { 4345 case FIELD: {
4232 PropertyDetails d = PropertyDetails(details.attributes(), 4346 PropertyDetails d = PropertyDetails(details.attributes(),
4233 NORMAL, 4347 NORMAL,
4234 Representation::None(), 4348 Representation::None(),
4235 details.descriptor_index()); 4349 details.descriptor_index());
4236 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); 4350 Object* value = RawFastPropertyAt(descs->GetFieldIndex(i));
4237 MaybeObject* maybe_dictionary = 4351 MaybeObject* maybe_dictionary =
4238 dictionary->Add(descs->GetKey(i), value, d); 4352 dictionary->Add(descs->GetKey(i), value, d);
4239 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 4353 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
4240 break; 4354 break;
4241 } 4355 }
4242 case CALLBACKS: { 4356 case CALLBACKS: {
4243 Object* value = descs->GetCallbacksObject(i); 4357 Object* value = descs->GetCallbacksObject(i);
4244 PropertyDetails d = PropertyDetails(details.attributes(), 4358 PropertyDetails d = PropertyDetails(details.attributes(),
4245 CALLBACKS, 4359 CALLBACKS,
4246 Representation::None(), 4360 Representation::None(),
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
4607 // If the object has fast properties, check whether the first slot 4721 // If the object has fast properties, check whether the first slot
4608 // in the descriptor array matches the hidden string. Since the 4722 // in the descriptor array matches the hidden string. Since the
4609 // hidden strings hash code is zero (and no other name has hash 4723 // hidden strings hash code is zero (and no other name has hash
4610 // code zero) it will always occupy the first entry if present. 4724 // code zero) it will always occupy the first entry if present.
4611 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4725 DescriptorArray* descriptors = this->map()->instance_descriptors();
4612 if (descriptors->number_of_descriptors() > 0) { 4726 if (descriptors->number_of_descriptors() > 0) {
4613 int sorted_index = descriptors->GetSortedKeyIndex(0); 4727 int sorted_index = descriptors->GetSortedKeyIndex(0);
4614 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4728 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4615 sorted_index < map()->NumberOfOwnDescriptors()) { 4729 sorted_index < map()->NumberOfOwnDescriptors()) {
4616 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4730 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4617 inline_value = 4731 MaybeObject* maybe_value = this->FastPropertyAt(
4618 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); 4732 descriptors->GetDetails(sorted_index).representation(),
4733 descriptors->GetFieldIndex(sorted_index));
4734 if (!maybe_value->To(&inline_value)) return maybe_value;
4619 } else { 4735 } else {
4620 inline_value = GetHeap()->undefined_value(); 4736 inline_value = GetHeap()->undefined_value();
4621 } 4737 }
4622 } else { 4738 } else {
4623 inline_value = GetHeap()->undefined_value(); 4739 inline_value = GetHeap()->undefined_value();
4624 } 4740 }
4625 } else { 4741 } else {
4626 PropertyAttributes attributes; 4742 PropertyAttributes attributes;
4627 // You can't install a getter on a property indexed by the hidden string, 4743 // You can't install a getter on a property indexed by the hidden string,
4628 // so we can be sure that GetLocalPropertyPostInterceptor returns a real 4744 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4677 // If the object has fast properties, check whether the first slot 4793 // If the object has fast properties, check whether the first slot
4678 // in the descriptor array matches the hidden string. Since the 4794 // in the descriptor array matches the hidden string. Since the
4679 // hidden strings hash code is zero (and no other name has hash 4795 // hidden strings hash code is zero (and no other name has hash
4680 // code zero) it will always occupy the first entry if present. 4796 // code zero) it will always occupy the first entry if present.
4681 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4797 DescriptorArray* descriptors = this->map()->instance_descriptors();
4682 if (descriptors->number_of_descriptors() > 0) { 4798 if (descriptors->number_of_descriptors() > 0) {
4683 int sorted_index = descriptors->GetSortedKeyIndex(0); 4799 int sorted_index = descriptors->GetSortedKeyIndex(0);
4684 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4800 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4685 sorted_index < map()->NumberOfOwnDescriptors()) { 4801 sorted_index < map()->NumberOfOwnDescriptors()) {
4686 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4802 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4687 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), 4803 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value);
4688 value);
4689 return this; 4804 return this;
4690 } 4805 }
4691 } 4806 }
4692 } 4807 }
4693 MaybeObject* store_result = 4808 MaybeObject* store_result =
4694 SetPropertyPostInterceptor(GetHeap()->hidden_string(), 4809 SetPropertyPostInterceptor(GetHeap()->hidden_string(),
4695 value, 4810 value,
4696 DONT_ENUM, 4811 DONT_ENUM,
4697 kNonStrictMode, 4812 kNonStrictMode,
4698 OMIT_EXTENSIBILITY_CHECK); 4813 OMIT_EXTENSIBILITY_CHECK);
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
5154 set_map(new_map); 5269 set_map(new_map);
5155 ASSERT(!map()->is_extensible()); 5270 ASSERT(!map()->is_extensible());
5156 return new_map; 5271 return new_map;
5157 } 5272 }
5158 5273
5159 5274
5160 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { 5275 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
5161 StackLimitCheck check(isolate); 5276 StackLimitCheck check(isolate);
5162 if (check.HasOverflowed()) return isolate->StackOverflow(); 5277 if (check.HasOverflowed()) return isolate->StackOverflow();
5163 5278
5279 if (map()->is_deprecated()) {
5280 MaybeObject* maybe_failure = MigrateInstance();
5281 if (maybe_failure->IsFailure()) return maybe_failure;
5282 }
5283
5164 Heap* heap = isolate->heap(); 5284 Heap* heap = isolate->heap();
5165 Object* result; 5285 Object* result;
5166 { MaybeObject* maybe_result = heap->CopyJSObject(this); 5286 { MaybeObject* maybe_result = heap->CopyJSObject(this);
5167 if (!maybe_result->ToObject(&result)) return maybe_result; 5287 if (!maybe_result->ToObject(&result)) return maybe_result;
5168 } 5288 }
5169 JSObject* copy = JSObject::cast(result); 5289 JSObject* copy = JSObject::cast(result);
5170 5290
5171 // Deep copy local properties. 5291 // Deep copy local properties.
5172 if (copy->HasFastProperties()) { 5292 if (copy->HasFastProperties()) {
5173 FixedArray* properties = copy->properties(); 5293 DescriptorArray* descriptors = copy->map()->instance_descriptors();
5174 for (int i = 0; i < properties->length(); i++) { 5294 int limit = copy->map()->NumberOfOwnDescriptors();
5175 Object* value = properties->get(i); 5295 for (int i = 0; i < limit; i++) {
5296 PropertyDetails details = descriptors->GetDetails(i);
5297 if (details.type() != FIELD) continue;
5298 int index = descriptors->GetFieldIndex(i);
5299 Object* value = RawFastPropertyAt(index);
5176 if (value->IsJSObject()) { 5300 if (value->IsJSObject()) {
5177 JSObject* js_object = JSObject::cast(value); 5301 JSObject* js_object = JSObject::cast(value);
5178 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); 5302 MaybeObject* maybe_copy = js_object->DeepCopy(isolate);
5179 if (!maybe_result->ToObject(&result)) return maybe_result; 5303 if (!maybe_copy->To(&value)) return maybe_copy;
5180 } 5304 } else {
5181 properties->set(i, result); 5305 Representation representation = details.representation();
5306 MaybeObject* maybe_storage =
5307 value->AllocateNewStorageFor(heap, representation);
5308 if (!maybe_storage->To(&value)) return maybe_storage;
5182 } 5309 }
5183 } 5310 copy->FastPropertyAtPut(index, value);
5184 int nof = copy->map()->inobject_properties();
5185 for (int i = 0; i < nof; i++) {
5186 Object* value = copy->InObjectPropertyAt(i);
5187 if (value->IsJSObject()) {
5188 JSObject* js_object = JSObject::cast(value);
5189 { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
5190 if (!maybe_result->ToObject(&result)) return maybe_result;
5191 }
5192 copy->InObjectPropertyAtPut(i, result);
5193 }
5194 } 5311 }
5195 } else { 5312 } else {
5196 { MaybeObject* maybe_result = 5313 { MaybeObject* maybe_result =
5197 heap->AllocateFixedArray(copy->NumberOfLocalProperties()); 5314 heap->AllocateFixedArray(copy->NumberOfLocalProperties());
5198 if (!maybe_result->ToObject(&result)) return maybe_result; 5315 if (!maybe_result->ToObject(&result)) return maybe_result;
5199 } 5316 }
5200 FixedArray* names = FixedArray::cast(result); 5317 FixedArray* names = FixedArray::cast(result);
5201 copy->GetLocalPropertyNames(names, 0); 5318 copy->GetLocalPropertyNames(names, 0);
5202 for (int i = 0; i < names->length(); i++) { 5319 for (int i = 0; i < names->length(); i++) {
5203 ASSERT(names->get(i)->IsString()); 5320 ASSERT(names->get(i)->IsString());
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
6011 return heap->undefined_value(); 6128 return heap->undefined_value();
6012 } 6129 }
6013 6130
6014 6131
6015 Object* JSObject::SlowReverseLookup(Object* value) { 6132 Object* JSObject::SlowReverseLookup(Object* value) {
6016 if (HasFastProperties()) { 6133 if (HasFastProperties()) {
6017 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); 6134 int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
6018 DescriptorArray* descs = map()->instance_descriptors(); 6135 DescriptorArray* descs = map()->instance_descriptors();
6019 for (int i = 0; i < number_of_own_descriptors; i++) { 6136 for (int i = 0; i < number_of_own_descriptors; i++) {
6020 if (descs->GetType(i) == FIELD) { 6137 if (descs->GetType(i) == FIELD) {
6021 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { 6138 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
6139 if (FLAG_track_double_fields &&
6140 descs->GetDetails(i).representation().IsDouble()) {
6141 ASSERT(property->IsHeapNumber());
6142 if (value->IsNumber() && property->Number() == value->Number()) {
6143 return descs->GetKey(i);
6144 }
6145 } else if (property == value) {
6022 return descs->GetKey(i); 6146 return descs->GetKey(i);
6023 } 6147 }
6024 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { 6148 } else if (descs->GetType(i) == CONSTANT_FUNCTION) {
6025 if (descs->GetConstantFunction(i) == value) { 6149 if (descs->GetConstantFunction(i) == value) {
6026 return descs->GetKey(i); 6150 return descs->GetKey(i);
6027 } 6151 }
6028 } 6152 }
6029 } 6153 }
6030 return GetHeap()->undefined_value(); 6154 return GetHeap()->undefined_value();
6031 } else { 6155 } else {
6032 return property_dictionary()->SlowReverseLookup(value); 6156 return property_dictionary()->SlowReverseLookup(value);
6033 } 6157 }
6034 } 6158 }
6035 6159
6036 6160
6037 MaybeObject* Map::RawCopy(int instance_size) { 6161 MaybeObject* Map::RawCopy(int instance_size) {
6038 Map* result; 6162 Map* result;
6039 MaybeObject* maybe_result = 6163 MaybeObject* maybe_result =
6040 GetHeap()->AllocateMap(instance_type(), instance_size); 6164 GetHeap()->AllocateMap(instance_type(), instance_size);
6041 if (!maybe_result->To(&result)) return maybe_result; 6165 if (!maybe_result->To(&result)) return maybe_result;
6042 6166
6043 result->set_prototype(prototype()); 6167 result->set_prototype(prototype());
6044 result->set_constructor(constructor()); 6168 result->set_constructor(constructor());
6045 result->set_bit_field(bit_field()); 6169 result->set_bit_field(bit_field());
6046 result->set_bit_field2(bit_field2()); 6170 result->set_bit_field2(bit_field2());
6047 int new_bit_field3 = bit_field3(); 6171 int new_bit_field3 = bit_field3();
6048 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); 6172 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
6049 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); 6173 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
6050 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); 6174 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache);
6175 new_bit_field3 = Deprecated::update(new_bit_field3, false);
6051 result->set_bit_field3(new_bit_field3); 6176 result->set_bit_field3(new_bit_field3);
6052 return result; 6177 return result;
6053 } 6178 }
6054 6179
6055 6180
6056 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, 6181 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
6057 NormalizedMapSharingMode sharing) { 6182 NormalizedMapSharingMode sharing) {
6058 int new_instance_size = instance_size(); 6183 int new_instance_size = instance_size();
6059 if (mode == CLEAR_INOBJECT_PROPERTIES) { 6184 if (mode == CLEAR_INOBJECT_PROPERTIES) {
6060 new_instance_size -= inobject_properties() * kPointerSize; 6185 new_instance_size -= inobject_properties() * kPointerSize;
(...skipping 9078 matching lines...) Expand 10 before | Expand all | Expand 10 after
15139 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 15264 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
15140 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 15265 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
15141 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 15266 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
15142 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 15267 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
15143 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 15268 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
15144 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 15269 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
15145 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 15270 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
15146 } 15271 }
15147 15272
15148 } } // namespace v8::internal 15273 } } // 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