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

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: 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
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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 value = result->holder()->FastPropertyAt(
820 result->GetFieldIndex().field_index()); 820 result->GetFieldIndex().field_index());
821 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 821 ASSERT(!value->IsTheHole() || result->IsReadOnly());
822 if (FLAG_track_double_fields && result->representation().IsDouble()) {
823 ASSERT(value->IsHeapNumber());
824 return heap->AllocateHeapNumber(value->Number());
danno 2013/05/07 13:04:47 If this happens too frequently (i.e. having to all
Toon Verwaest 2013/05/07 15:08:52 Done.
825 }
822 return value->IsTheHole() ? heap->undefined_value() : value; 826 return value->IsTheHole() ? heap->undefined_value() : value;
823 case CONSTANT_FUNCTION: 827 case CONSTANT_FUNCTION:
824 return result->GetConstantFunction(); 828 return result->GetConstantFunction();
825 case CALLBACKS: 829 case CALLBACKS:
826 return result->holder()->GetPropertyWithCallback( 830 return result->holder()->GetPropertyWithCallback(
827 receiver, result->GetCallbackObject(), name); 831 receiver, result->GetCallbackObject(), name);
828 case HANDLER: 832 case HANDLER:
829 return result->proxy()->GetPropertyWithHandler(receiver, name); 833 return result->proxy()->GetPropertyWithHandler(receiver, name);
830 case INTERCEPTOR: 834 case INTERCEPTOR:
831 return result->holder()->GetPropertyWithInterceptor( 835 return result->holder()->GetPropertyWithInterceptor(
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 } 1708 }
1705 // TODO(rossberg): what about proxies? 1709 // TODO(rossberg): what about proxies?
1706 // If the constructor is not present, return "Object". 1710 // If the constructor is not present, return "Object".
1707 return GetHeap()->Object_string(); 1711 return GetHeap()->Object_string();
1708 } 1712 }
1709 1713
1710 1714
1711 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1715 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1712 Name* name, 1716 Name* name,
1713 Object* value, 1717 Object* value,
1714 int field_index) { 1718 int field_index,
1719 Representation representation) {
danno 2013/05/07 13:04:47 Perhaps a comment that this is a transition case.
Toon Verwaest 2013/05/07 15:08:52 Done.
1720 Object* storage = value;
1721 if (FLAG_track_double_fields && representation.IsDouble()) {
danno 2013/05/07 13:04:47 Don't you just have to write into the existing box
Toon Verwaest 2013/05/07 15:08:52 It is the transition case; added comment. On 2013
1722 MaybeObject* maybe_storage = GetHeap()->AllocateHeapNumber(value->Number());
1723 if (!maybe_storage->To(&storage)) return maybe_storage;
1724 }
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
1786 if (map()->unused_property_fields() == 0) { 1800 if (map()->unused_property_fields() == 0) {
danno 2013/05/07 13:04:47 Add a TODO to merge the second half of this method
Toon Verwaest 2013/05/07 15:08:52 Done.
1787 // Make room for the new value 1801 // Make room for the new value
1788 MaybeObject* maybe_values = 1802 MaybeObject* maybe_values =
1789 properties()->CopySize(properties()->length() + kFieldsAdded); 1803 properties()->CopySize(properties()->length() + kFieldsAdded);
1790 if (!maybe_values->To(&values)) return maybe_values; 1804 if (!maybe_values->To(&values)) return maybe_values;
1791 } 1805 }
1792 1806
1793 TransitionFlag flag = INSERT_TRANSITION; 1807 TransitionFlag flag = INSERT_TRANSITION;
1794 1808
1809 Heap* heap = isolate->heap();
1810
1795 Map* new_map; 1811 Map* new_map;
1796 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); 1812 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
1797 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 1813 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
1798 1814
1815 Object* storage;
1816 MaybeObject* maybe_storage = value->StorageFor(heap, representation);
1817 if (!maybe_storage->To(&storage)) return maybe_storage;
1818
1799 if (map()->unused_property_fields() == 0) { 1819 if (map()->unused_property_fields() == 0) {
1800 ASSERT(values != NULL); 1820 ASSERT(values != NULL);
1801 set_properties(values); 1821 set_properties(values);
1802 new_map->set_unused_property_fields(kFieldsAdded - 1); 1822 new_map->set_unused_property_fields(kFieldsAdded - 1);
1803 } else { 1823 } else {
1804 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); 1824 new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
1805 } 1825 }
1806 1826
1807 set_map(new_map); 1827 set_map(new_map);
1808 return FastPropertyAtPut(index, value); 1828
1829 FastPropertyAtPut(index, storage);
1830 return value;
1809 } 1831 }
1810 1832
1811 1833
1812 MaybeObject* JSObject::AddConstantFunctionProperty( 1834 MaybeObject* JSObject::AddConstantFunctionProperty(
1813 Name* name, 1835 Name* name,
1814 JSFunction* function, 1836 JSFunction* function,
1815 PropertyAttributes attributes) { 1837 PropertyAttributes attributes) {
1816 // Allocate new instance descriptors with (name, function) added 1838 // Allocate new instance descriptors with (name, function) added
1817 ConstantFunctionDescriptor d(name, function, attributes, 0); 1839 ConstantFunctionDescriptor d(name, function, attributes, 0);
1818 1840
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 Object* new_value, 2086 Object* new_value,
2065 PropertyAttributes attributes) { 2087 PropertyAttributes attributes) {
2066 if (map()->unused_property_fields() == 0 && 2088 if (map()->unused_property_fields() == 0 &&
2067 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { 2089 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
2068 Object* obj; 2090 Object* obj;
2069 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2091 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2070 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2092 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2071 return ReplaceSlowProperty(name, new_value, attributes); 2093 return ReplaceSlowProperty(name, new_value, attributes);
2072 } 2094 }
2073 2095
2096 Representation representation = new_value->OptimalRepresentation();
2074 int index = map()->NextFreePropertyIndex(); 2097 int index = map()->NextFreePropertyIndex();
2075 FieldDescriptor new_field( 2098 FieldDescriptor new_field(name, index, attributes, representation, 0);
2076 name, index, attributes, new_value->OptimalRepresentation(), 0);
2077 2099
2078 // Make a new map for the object. 2100 // Make a new map for the object.
2079 Map* new_map; 2101 Map* new_map;
2080 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, 2102 MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field,
2081 OMIT_TRANSITION); 2103 OMIT_TRANSITION);
2082 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2104 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2083 2105
2084 // Make new properties array if necessary. 2106 // Make new properties array if necessary.
2085 FixedArray* new_properties = NULL; 2107 FixedArray* new_properties = NULL;
2086 int new_unused_property_fields = map()->unused_property_fields() - 1; 2108 int new_unused_property_fields = map()->unused_property_fields() - 1;
2087 if (map()->unused_property_fields() == 0) { 2109 if (map()->unused_property_fields() == 0) {
2088 new_unused_property_fields = kFieldsAdded - 1; 2110 new_unused_property_fields = kFieldsAdded - 1;
2089 MaybeObject* maybe_new_properties = 2111 MaybeObject* maybe_new_properties =
2090 properties()->CopySize(properties()->length() + kFieldsAdded); 2112 properties()->CopySize(properties()->length() + kFieldsAdded);
2091 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties; 2113 if (!maybe_new_properties->To(&new_properties)) return maybe_new_properties;
2092 } 2114 }
2093 2115
2116 Heap* heap = GetHeap();
2117 Object* storage;
2118 MaybeObject* maybe_storage = new_value->StorageFor(heap, representation);
2119 if (!maybe_storage->To(&storage)) return maybe_storage;
2120
2094 // Update pointers to commit changes. 2121 // Update pointers to commit changes.
2095 // Object points to the new map. 2122 // Object points to the new map.
2096 new_map->set_unused_property_fields(new_unused_property_fields); 2123 new_map->set_unused_property_fields(new_unused_property_fields);
2097 set_map(new_map); 2124 set_map(new_map);
2098 if (new_properties != NULL) { 2125 if (new_properties != NULL) {
2099 set_properties(new_properties); 2126 set_properties(new_properties);
2100 } 2127 }
2101 return FastPropertyAtPut(index, new_value); 2128 FastPropertyAtPut(index, new_value);
2129 return new_value;
2102 } 2130 }
2103 2131
2104 2132
2105 const char* Representation::Mnemonic() const { 2133 const char* Representation::Mnemonic() const {
2106 switch (kind_) { 2134 switch (kind_) {
2107 case kNone: return "v"; 2135 case kNone: return "v";
2108 case kTagged: return "t"; 2136 case kTagged: return "t";
2109 case kSmi: return "s"; 2137 case kSmi: return "s";
2110 case kDouble: return "d"; 2138 case kDouble: return "d";
2111 case kInteger32: return "i"; 2139 case kInteger32: return "i";
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) { 2187 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
2160 if (trim_mode == FROM_GC) { 2188 if (trim_mode == FROM_GC) {
2161 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta); 2189 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
2162 } else { 2190 } else {
2163 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta); 2191 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2164 } 2192 }
2165 } 2193 }
2166 } 2194 }
2167 2195
2168 2196
2169 bool Map::InstancesNeedRewriting(int target_number_of_fields, 2197 bool Map::InstancesNeedRewriting(Map* target,
2198 int target_number_of_fields,
2170 int target_inobject, 2199 int target_inobject,
2171 int target_unused) { 2200 int target_unused) {
2172 // If fields were added (or removed), rewrite the instance. 2201 // If fields were added (or removed), rewrite the instance.
2173 int number_of_fields = NumberOfFields(); 2202 int number_of_fields = NumberOfFields();
2174 ASSERT(target_number_of_fields >= number_of_fields); 2203 ASSERT(target_number_of_fields >= number_of_fields);
2175 if (target_number_of_fields != number_of_fields) return true; 2204 if (target_number_of_fields != number_of_fields) return true;
2205
2206 if (FLAG_track_double_fields) {
2207 // If smi descriptors were replaced by double descriptors, rewrite.
2208 DescriptorArray* old_desc = instance_descriptors();
2209 DescriptorArray* new_desc = target->instance_descriptors();
2210 int limit = NumberOfOwnDescriptors();
2211 for (int i = 0; i < limit; i++) {
2212 if (new_desc->GetDetails(i).representation().IsDouble() &&
2213 old_desc->GetDetails(i).representation().IsSmi()) {
2214 return true;
2215 }
2216 }
2217 }
2218
2176 // If no fields were added, and no inobject properties were removed, setting 2219 // If no fields were added, and no inobject properties were removed, setting
2177 // the map is sufficient. 2220 // the map is sufficient.
2178 if (target_inobject == inobject_properties()) return false; 2221 if (target_inobject == inobject_properties()) return false;
2179 // In-object slack tracking may have reduced the object size of the new map. 2222 // 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 2223 // In that case, succeed if all existing fields were inobject, and they still
2181 // fit within the new inobject size. 2224 // fit within the new inobject size.
2182 ASSERT(target_inobject < inobject_properties()); 2225 ASSERT(target_inobject < inobject_properties());
2183 if (target_number_of_fields <= target_inobject) { 2226 if (target_number_of_fields <= target_inobject) {
2184 ASSERT(target_number_of_fields + target_unused == target_inobject); 2227 ASSERT(target_number_of_fields + target_unused == target_inobject);
2185 return false; 2228 return false;
(...skipping 19 matching lines...) Expand all
2205 // * If there are properties left in the backing store, install the backing 2248 // * If there are properties left in the backing store, install the backing
2206 // store. 2249 // store.
2207 MaybeObject* JSObject::MigrateToMap(Map* new_map) { 2250 MaybeObject* JSObject::MigrateToMap(Map* new_map) {
2208 Heap* heap = GetHeap(); 2251 Heap* heap = GetHeap();
2209 Map* old_map = map(); 2252 Map* old_map = map();
2210 int number_of_fields = new_map->NumberOfFields(); 2253 int number_of_fields = new_map->NumberOfFields();
2211 int inobject = new_map->inobject_properties(); 2254 int inobject = new_map->inobject_properties();
2212 int unused = new_map->unused_property_fields(); 2255 int unused = new_map->unused_property_fields();
2213 2256
2214 // Nothing to do if no functions were converted to fields. 2257 // Nothing to do if no functions were converted to fields.
2215 if (!old_map->InstancesNeedRewriting(number_of_fields, inobject, unused)) { 2258 if (!old_map->InstancesNeedRewriting(
2259 new_map, number_of_fields, inobject, unused)) {
2216 set_map(new_map); 2260 set_map(new_map);
2217 return this; 2261 return this;
2218 } 2262 }
2219 2263
2220 int total_size = number_of_fields + unused; 2264 int total_size = number_of_fields + unused;
2221 int external = total_size - inobject; 2265 int external = total_size - inobject;
2222 FixedArray* array; 2266 FixedArray* array;
2223 MaybeObject* maybe_array = heap->AllocateFixedArray(total_size); 2267 MaybeObject* maybe_array = heap->AllocateFixedArray(total_size);
2224 if (!maybe_array->To(&array)) return maybe_array; 2268 if (!maybe_array->To(&array)) return maybe_array;
2225 2269
2226 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2270 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2227 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2271 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2228 int descriptors = new_map->NumberOfOwnDescriptors(); 2272 int descriptors = new_map->NumberOfOwnDescriptors();
2229 2273
2230 for (int i = 0; i < descriptors; i++) { 2274 for (int i = 0; i < descriptors; i++) {
2231 PropertyDetails details = new_descriptors->GetDetails(i); 2275 PropertyDetails details = new_descriptors->GetDetails(i);
2232 if (details.type() != FIELD) continue; 2276 if (details.type() != FIELD) continue;
2233 PropertyDetails old_details = old_descriptors->GetDetails(i); 2277 PropertyDetails old_details = old_descriptors->GetDetails(i);
2234 ASSERT(old_details.type() == CONSTANT_FUNCTION || 2278 ASSERT(old_details.type() == CONSTANT_FUNCTION ||
2235 old_details.type() == FIELD); 2279 old_details.type() == FIELD);
2236 Object* value = old_details.type() == CONSTANT_FUNCTION 2280 Object* value = old_details.type() == CONSTANT_FUNCTION
2237 ? old_descriptors->GetValue(i) 2281 ? old_descriptors->GetValue(i)
2238 : FastPropertyAt(old_descriptors->GetFieldIndex(i)); 2282 : FastPropertyAt(old_descriptors->GetFieldIndex(i));
2283 if (FLAG_track_double_fields &&
2284 old_details.representation().IsSmi() &&
2285 details.representation().IsDouble()) {
2286 // Objects must be allocated in the old object space, since the
2287 // overall number of HeapNumbers needed for the conversion might
2288 // exceed the capacity of new space, and we would fail repeatedly
2289 // trying to migrate the instance.
2290 MaybeObject* maybe_storage =
2291 heap->AllocateHeapNumber(Smi::cast(value)->value(), TENURED);
danno 2013/05/07 13:04:47 AllocateNewStorageFor
Toon Verwaest 2013/05/07 15:08:52 Done.
2292 if (!maybe_storage->To(&value)) return maybe_storage;
2293 }
2294 ASSERT(!(FLAG_track_double_fields &&
2295 details.representation().IsDouble() &&
2296 value->IsSmi()));
2239 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2297 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2240 if (target_index < 0) target_index += total_size; 2298 if (target_index < 0) target_index += total_size;
2241 array->set(target_index, value); 2299 array->set(target_index, value);
2242 } 2300 }
2243 2301
2244 // From here on we cannot fail anymore. 2302 // From here on we cannot fail anymore.
2245 2303
2246 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2304 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2247 // avoid overwriting |one_pointer_filler_map|. 2305 // avoid overwriting |one_pointer_filler_map|.
2248 int limit = Min(inobject, number_of_fields); 2306 int limit = Min(inobject, number_of_fields);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 } 2351 }
2294 2352
2295 2353
2296 MaybeObject* Map::CopyGeneralizeAllRepresentations() { 2354 MaybeObject* Map::CopyGeneralizeAllRepresentations() {
2297 Map* new_map; 2355 Map* new_map;
2298 MaybeObject* maybe_map = this->Copy(); 2356 MaybeObject* maybe_map = this->Copy();
2299 if (!maybe_map->To(&new_map)) return maybe_map; 2357 if (!maybe_map->To(&new_map)) return maybe_map;
2300 2358
2301 new_map->instance_descriptors()->InitializeRepresentations( 2359 new_map->instance_descriptors()->InitializeRepresentations(
2302 Representation::Tagged()); 2360 Representation::Tagged());
2361 if (FLAG_trace_generalization) {
2362 PrintF("failed generalization %p -> %p\n",
2363 static_cast<void*>(this), static_cast<void*>(new_map));
2364 }
2303 return new_map; 2365 return new_map;
2304 } 2366 }
2305 2367
2306 2368
2307 void Map::DeprecateTransitionTree() { 2369 void Map::DeprecateTransitionTree() {
2308 if (!FLAG_track_fields) return; 2370 if (!FLAG_track_fields) return;
2309 if (is_deprecated()) return; 2371 if (is_deprecated()) return;
2310 if (HasTransitionArray()) { 2372 if (HasTransitionArray()) {
2311 TransitionArray* transitions = this->transitions(); 2373 TransitionArray* transitions = this->transitions();
2312 for (int i = 0; i < transitions->number_of_transitions(); i++) { 2374 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( 2520 Map* updated = root_map->FindUpdatedMap(
2459 verbatim, descriptors, old_descriptors); 2521 verbatim, descriptors, old_descriptors);
2460 // Check the state of the root map. 2522 // Check the state of the root map.
2461 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2523 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2462 2524
2463 int valid = updated->NumberOfOwnDescriptors(); 2525 int valid = updated->NumberOfOwnDescriptors();
2464 if (updated_descriptors->IsMoreGeneralThan( 2526 if (updated_descriptors->IsMoreGeneralThan(
2465 verbatim, valid, descriptors, old_descriptors)) { 2527 verbatim, valid, descriptors, old_descriptors)) {
2466 Representation updated_representation = 2528 Representation updated_representation =
2467 updated_descriptors->GetDetails(modify_index).representation(); 2529 updated_descriptors->GetDetails(modify_index).representation();
2468 if (new_representation.fits_into(updated_representation)) return updated; 2530 if (new_representation.fits_into(updated_representation)) {
2531 if (FLAG_trace_generalization) {
2532 PrintF("migrating to existing map %p -> %p\n",
2533 static_cast<void*>(this), static_cast<void*>(updated));
2534 }
2535 return updated;
2536 }
2469 } 2537 }
2470 2538
2471 DescriptorArray* new_descriptors; 2539 DescriptorArray* new_descriptors;
2472 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2540 MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2473 verbatim, valid, descriptors, old_descriptors); 2541 verbatim, valid, descriptors, old_descriptors);
2474 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 2542 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2475 2543
2476 old_reprepresentation = 2544 old_reprepresentation =
2477 new_descriptors->GetDetails(modify_index).representation(); 2545 new_descriptors->GetDetails(modify_index).representation();
2478 new_representation = new_representation.generalize(old_reprepresentation); 2546 new_representation = new_representation.generalize(old_reprepresentation);
2479 new_descriptors->SetRepresentation(modify_index, new_representation); 2547 new_descriptors->SetRepresentation(modify_index, new_representation);
2480 2548
2481 Map* split_map = root_map->FindLastMatchMap( 2549 Map* split_map = root_map->FindLastMatchMap(
2482 verbatim, descriptors, new_descriptors); 2550 verbatim, descriptors, new_descriptors);
2483 2551
2484 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2552 int split_descriptors = split_map->NumberOfOwnDescriptors();
2485 // This is shadowed by |updated_descriptors| being more general than 2553 // This is shadowed by |updated_descriptors| being more general than
2486 // |old_descriptors|. 2554 // |old_descriptors|.
2487 ASSERT(descriptors != split_descriptors); 2555 ASSERT(descriptors != split_descriptors);
2488 2556
2489 int descriptor = split_descriptors; 2557 int descriptor = split_descriptors;
2490 split_map->DeprecateTarget( 2558 split_map->DeprecateTarget(
2491 old_descriptors->GetKey(descriptor), new_descriptors); 2559 old_descriptors->GetKey(descriptor), new_descriptors);
2492 2560
2561 if (FLAG_trace_generalization) {
2562 PrintF("migrating to new map %p -> %p (%i steps)\n",
2563 static_cast<void*>(this),
2564 static_cast<void*>(new_descriptors),
2565 descriptors - descriptor);
2566 }
2567
2493 Map* new_map = split_map; 2568 Map* new_map = split_map;
2494 // Add missing transitions. 2569 // Add missing transitions.
2495 for (; descriptor < descriptors; descriptor++) { 2570 for (; descriptor < descriptors; descriptor++) {
2496 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2571 MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2497 descriptor, new_descriptors); 2572 descriptor, new_descriptors);
2498 if (!maybe_map->To(&new_map)) { 2573 if (!maybe_map->To(&new_map)) {
2499 // Create a handle for the last created map to ensure it stays alive 2574 // 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 2575 // during GC. Its descriptor array is too large, but it will be
2501 // overwritten during retry anyway. 2576 // overwritten during retry anyway.
2502 Handle<Map>(new_map); 2577 Handle<Map>(new_map);
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 3541
3467 3542
3468 void JSObject::TransitionToMap(Handle<JSObject> object, Handle<Map> map) { 3543 void JSObject::TransitionToMap(Handle<JSObject> object, Handle<Map> map) {
3469 CALL_HEAP_FUNCTION_VOID( 3544 CALL_HEAP_FUNCTION_VOID(
3470 object->GetIsolate(), 3545 object->GetIsolate(),
3471 object->TransitionToMap(*map)); 3546 object->TransitionToMap(*map));
3472 } 3547 }
3473 3548
3474 3549
3475 void JSObject::MigrateInstance(Handle<JSObject> object) { 3550 void JSObject::MigrateInstance(Handle<JSObject> object) {
3551 if (FLAG_trace_migration) {
3552 PrintF("migrating instance %p (%p)\n",
3553 static_cast<void*>(*object),
3554 static_cast<void*>(object->map()));
3555 }
3476 CALL_HEAP_FUNCTION_VOID( 3556 CALL_HEAP_FUNCTION_VOID(
3477 object->GetIsolate(), 3557 object->GetIsolate(),
3478 object->MigrateInstance()); 3558 object->MigrateInstance());
3479 } 3559 }
3480 3560
3481 3561
3482 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3562 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
3483 int modify_index, 3563 int modify_index,
3484 Representation new_representation) { 3564 Representation representation) {
3485 CALL_HEAP_FUNCTION( 3565 CALL_HEAP_FUNCTION(
3486 map->GetIsolate(), 3566 map->GetIsolate(),
3487 map->GeneralizeRepresentation(modify_index, new_representation), 3567 map->GeneralizeRepresentation(modify_index, representation),
3488 Map); 3568 Map);
3489 } 3569 }
3490 3570
3491 3571
3492 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3572 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3493 Name* name_raw, 3573 Name* name_raw,
3494 Object* value_raw, 3574 Object* value_raw,
3495 PropertyAttributes attributes, 3575 PropertyAttributes attributes,
3496 StrictModeFlag strict_mode, 3576 StrictModeFlag strict_mode,
3497 StoreFromKeyed store_mode) { 3577 StoreFromKeyed store_mode) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3577 case NORMAL: 3657 case NORMAL:
3578 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3658 result = lookup->holder()->SetNormalizedProperty(lookup, *value);
3579 break; 3659 break;
3580 case FIELD: { 3660 case FIELD: {
3581 Representation representation = lookup->representation(); 3661 Representation representation = lookup->representation();
3582 if (!value->FitsRepresentation(representation)) { 3662 if (!value->FitsRepresentation(representation)) {
3583 MaybeObject* maybe_failure = 3663 MaybeObject* maybe_failure =
3584 lookup->holder()->GeneralizeFieldRepresentation( 3664 lookup->holder()->GeneralizeFieldRepresentation(
3585 lookup->GetDescriptorIndex(), value->OptimalRepresentation()); 3665 lookup->GetDescriptorIndex(), value->OptimalRepresentation());
3586 if (maybe_failure->IsFailure()) return maybe_failure; 3666 if (maybe_failure->IsFailure()) return maybe_failure;
3667 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3668 int descriptor = lookup->GetDescriptorIndex();
3669 representation = desc->GetDetails(descriptor).representation();
3587 } 3670 }
3588 result = lookup->holder()->FastPropertyAtPut( 3671 if (FLAG_track_double_fields && representation.IsDouble()) {
3672 HeapNumber* storage =
3673 HeapNumber::cast(lookup->holder()->FastPropertyAt(
3674 lookup->GetFieldIndex().field_index()));
3675 storage->set_value(value->Number());
3676 result = *value;
3677 break;
3678 }
3679 lookup->holder()->FastPropertyAtPut(
3589 lookup->GetFieldIndex().field_index(), *value); 3680 lookup->GetFieldIndex().field_index(), *value);
3681 result = *value;
3590 break; 3682 break;
3591 } 3683 }
3592 case CONSTANT_FUNCTION: 3684 case CONSTANT_FUNCTION:
3593 // Only replace the function if necessary. 3685 // Only replace the function if necessary.
3594 if (*value == lookup->GetConstantFunction()) return *value; 3686 if (*value == lookup->GetConstantFunction()) return *value;
3595 // Preserve the attributes of this existing property. 3687 // Preserve the attributes of this existing property.
3596 attributes = lookup->GetAttributes(); 3688 attributes = lookup->GetAttributes();
3597 result = 3689 result =
3598 lookup->holder()->ConvertDescriptorToField(*name, *value, attributes); 3690 lookup->holder()->ConvertDescriptorToField(*name, *value, attributes);
3599 break; 3691 break;
3600 case CALLBACKS: { 3692 case CALLBACKS: {
3601 Object* callback_object = lookup->GetCallbackObject(); 3693 Object* callback_object = lookup->GetCallbackObject();
3602 return self->SetPropertyWithCallback( 3694 return self->SetPropertyWithCallback(
3603 callback_object, *name, *value, lookup->holder(), strict_mode); 3695 callback_object, *name, *value, lookup->holder(), strict_mode);
3604 } 3696 }
3605 case INTERCEPTOR: 3697 case INTERCEPTOR:
3606 result = lookup->holder()->SetPropertyWithInterceptor( 3698 result = lookup->holder()->SetPropertyWithInterceptor(
3607 *name, *value, attributes, strict_mode); 3699 *name, *value, attributes, strict_mode);
3608 break; 3700 break;
3609 case TRANSITION: { 3701 case TRANSITION: {
3610 Map* transition_map = lookup->GetTransitionTarget(); 3702 Map* transition_map = lookup->GetTransitionTarget();
3611 int descriptor = transition_map->LastAdded(); 3703 int descriptor = transition_map->LastAdded();
3612 3704
3613 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3705 DescriptorArray* descriptors = transition_map->instance_descriptors();
3614 PropertyDetails details = descriptors->GetDetails(descriptor); 3706 PropertyDetails details = descriptors->GetDetails(descriptor);
3615 3707
3616 if (details.type() == FIELD) { 3708 if (details.type() == FIELD) {
3617 if (attributes == details.attributes()) { 3709 if (attributes == details.attributes()) {
3618 if (!value->FitsRepresentation(details.representation())) { 3710 Representation representation = details.representation();
3711 if (!value->FitsRepresentation(representation)) {
3619 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3712 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3620 descriptor, value->OptimalRepresentation()); 3713 descriptor, value->OptimalRepresentation());
3621 if (!maybe_map->To(&transition_map)) return maybe_map; 3714 if (!maybe_map->To(&transition_map)) return maybe_map;
3622 Object* back = transition_map->GetBackPointer(); 3715 Object* back = transition_map->GetBackPointer();
3623 if (back->IsMap()) { 3716 if (back->IsMap()) {
3624 MaybeObject* maybe_failure = 3717 MaybeObject* maybe_failure =
3625 lookup->holder()->MigrateToMap(Map::cast(back)); 3718 lookup->holder()->MigrateToMap(Map::cast(back));
3626 if (maybe_failure->IsFailure()) return maybe_failure; 3719 if (maybe_failure->IsFailure()) return maybe_failure;
3627 } 3720 }
3721 DescriptorArray* desc = transition_map->instance_descriptors();
3722 int descriptor = transition_map->LastAdded();
3723 representation = desc->GetDetails(descriptor).representation();
3628 } 3724 }
3629 int field_index = descriptors->GetFieldIndex(descriptor); 3725 int field_index = descriptors->GetFieldIndex(descriptor);
3630 result = lookup->holder()->AddFastPropertyUsingMap( 3726 result = lookup->holder()->AddFastPropertyUsingMap(
3631 transition_map, *name, *value, field_index); 3727 transition_map, *name, *value, field_index, representation);
3632 } else { 3728 } else {
3633 result = lookup->holder()->ConvertDescriptorToField( 3729 result = lookup->holder()->ConvertDescriptorToField(
3634 *name, *value, attributes); 3730 *name, *value, attributes);
3635 } 3731 }
3636 } else if (details.type() == CALLBACKS) { 3732 } else if (details.type() == CALLBACKS) {
3637 result = lookup->holder()->ConvertDescriptorToField( 3733 result = lookup->holder()->ConvertDescriptorToField(
3638 *name, *value, attributes); 3734 *name, *value, attributes);
3639 } else { 3735 } else {
3640 ASSERT(details.type() == CONSTANT_FUNCTION); 3736 ASSERT(details.type() == CONSTANT_FUNCTION);
3641 3737
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3762 attributes, NORMAL, Representation::None()); 3858 attributes, NORMAL, Representation::None());
3763 result = self->SetNormalizedProperty(*name, *value, details); 3859 result = self->SetNormalizedProperty(*name, *value, details);
3764 break; 3860 break;
3765 } 3861 }
3766 case FIELD: { 3862 case FIELD: {
3767 Representation representation = lookup.representation(); 3863 Representation representation = lookup.representation();
3768 if (!value->FitsRepresentation(representation)) { 3864 if (!value->FitsRepresentation(representation)) {
3769 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( 3865 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation(
3770 lookup.GetDescriptorIndex(), value->OptimalRepresentation()); 3866 lookup.GetDescriptorIndex(), value->OptimalRepresentation());
3771 if (maybe_failure->IsFailure()) return maybe_failure; 3867 if (maybe_failure->IsFailure()) return maybe_failure;
3868 DescriptorArray* desc = self->map()->instance_descriptors();
3869 int descriptor = lookup.GetDescriptorIndex();
3870 representation = desc->GetDetails(descriptor).representation();
3772 } 3871 }
3773 result = self->FastPropertyAtPut( 3872 if (FLAG_track_double_fields && representation.IsDouble()) {
3774 lookup.GetFieldIndex().field_index(), *value); 3873 HeapNumber* storage =
3874 HeapNumber::cast(self->FastPropertyAt(
3875 lookup.GetFieldIndex().field_index()));
3876 storage->set_value(value->Number());
3877 result = *value;
3878 break;
3879 }
3880 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value);
3881 result = *value;
3775 break; 3882 break;
3776 } 3883 }
3777 case CONSTANT_FUNCTION: 3884 case CONSTANT_FUNCTION:
3778 // Only replace the function if necessary. 3885 // Only replace the function if necessary.
3779 if (*value != lookup.GetConstantFunction()) { 3886 if (*value != lookup.GetConstantFunction()) {
3780 // Preserve the attributes of this existing property. 3887 // Preserve the attributes of this existing property.
3781 attributes = lookup.GetAttributes(); 3888 attributes = lookup.GetAttributes();
3782 result = self->ConvertDescriptorToField(*name, *value, attributes); 3889 result = self->ConvertDescriptorToField(*name, *value, attributes);
3783 } 3890 }
3784 break; 3891 break;
3785 case CALLBACKS: 3892 case CALLBACKS:
3786 case INTERCEPTOR: 3893 case INTERCEPTOR:
3787 // Override callback in clone 3894 // Override callback in clone
3788 result = self->ConvertDescriptorToField(*name, *value, attributes); 3895 result = self->ConvertDescriptorToField(*name, *value, attributes);
3789 break; 3896 break;
3790 case TRANSITION: { 3897 case TRANSITION: {
3791 Map* transition_map = lookup.GetTransitionTarget(); 3898 Map* transition_map = lookup.GetTransitionTarget();
3792 int descriptor = transition_map->LastAdded(); 3899 int descriptor = transition_map->LastAdded();
3793 3900
3794 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3901 DescriptorArray* descriptors = transition_map->instance_descriptors();
3795 PropertyDetails details = descriptors->GetDetails(descriptor); 3902 PropertyDetails details = descriptors->GetDetails(descriptor);
3796 3903
3797 if (details.type() == FIELD) { 3904 if (details.type() == FIELD) {
3798 if (attributes == details.attributes()) { 3905 if (attributes == details.attributes()) {
3799 if (!value->FitsRepresentation(details.representation())) { 3906 Representation representation = details.representation();
3907 if (!value->FitsRepresentation(representation)) {
3800 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( 3908 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3801 descriptor, value->OptimalRepresentation()); 3909 descriptor, value->OptimalRepresentation());
3802 if (!maybe_map->To(&transition_map)) return maybe_map; 3910 if (!maybe_map->To(&transition_map)) return maybe_map;
3803 Object* back = transition_map->GetBackPointer(); 3911 Object* back = transition_map->GetBackPointer();
3804 if (back->IsMap()) { 3912 if (back->IsMap()) {
3805 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back)); 3913 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back));
3806 if (maybe_failure->IsFailure()) return maybe_failure; 3914 if (maybe_failure->IsFailure()) return maybe_failure;
3807 } 3915 }
3916 DescriptorArray* desc = transition_map->instance_descriptors();
3917 int descriptor = transition_map->LastAdded();
3918 representation = desc->GetDetails(descriptor).representation();
3808 } 3919 }
3809 int field_index = descriptors->GetFieldIndex(descriptor); 3920 int field_index = descriptors->GetFieldIndex(descriptor);
3810 result = self->AddFastPropertyUsingMap( 3921 result = lookup.holder()->AddFastPropertyUsingMap(
danno 2013/05/07 13:04:47 Can you please revert to self?
Toon Verwaest 2013/05/07 15:08:52 Done.
3811 transition_map, *name, *value, field_index); 3922 transition_map, *name, *value, field_index, representation);
3812 } else { 3923 } else {
3813 result = self->ConvertDescriptorToField(*name, *value, attributes); 3924 result = self->ConvertDescriptorToField(*name, *value, attributes);
3814 } 3925 }
3815 } else if (details.type() == CALLBACKS) { 3926 } else if (details.type() == CALLBACKS) {
3816 result = self->ConvertDescriptorToField(*name, *value, attributes); 3927 result = self->ConvertDescriptorToField(*name, *value, attributes);
3817 } else { 3928 } else {
3818 ASSERT(details.type() == CONSTANT_FUNCTION); 3929 ASSERT(details.type() == CONSTANT_FUNCTION);
3819 3930
3820 // Replace transition to CONSTANT FUNCTION with a map transition to a 3931 // Replace transition to CONSTANT FUNCTION with a map transition to a
3821 // new map with a FIELD, even if the value is a function. 3932 // new map with a FIELD, even if the value is a function.
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
4609 // hidden strings hash code is zero (and no other name has hash 4720 // hidden strings hash code is zero (and no other name has hash
4610 // code zero) it will always occupy the first entry if present. 4721 // code zero) it will always occupy the first entry if present.
4611 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4722 DescriptorArray* descriptors = this->map()->instance_descriptors();
4612 if (descriptors->number_of_descriptors() > 0) { 4723 if (descriptors->number_of_descriptors() > 0) {
4613 int sorted_index = descriptors->GetSortedKeyIndex(0); 4724 int sorted_index = descriptors->GetSortedKeyIndex(0);
4614 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4725 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4615 sorted_index < map()->NumberOfOwnDescriptors()) { 4726 sorted_index < map()->NumberOfOwnDescriptors()) {
4616 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4727 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4617 inline_value = 4728 inline_value =
4618 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index)); 4729 this->FastPropertyAt(descriptors->GetFieldIndex(sorted_index));
4730 if (FLAG_track_double_fields &&
4731 descriptors->GetDetails(sorted_index).representation().IsDouble() &&
4732 init_option == ONLY_RETURN_INLINE_VALUE) {
4733 ASSERT(inline_value->IsHeapNumber());
4734 return GetHeap()->AllocateHeapNumber(inline_value->Number());
4735 }
4619 } else { 4736 } else {
4620 inline_value = GetHeap()->undefined_value(); 4737 inline_value = GetHeap()->undefined_value();
4621 } 4738 }
4622 } else { 4739 } else {
4623 inline_value = GetHeap()->undefined_value(); 4740 inline_value = GetHeap()->undefined_value();
4624 } 4741 }
4625 } else { 4742 } else {
4626 PropertyAttributes attributes; 4743 PropertyAttributes attributes;
4627 // You can't install a getter on a property indexed by the hidden string, 4744 // 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 4745 // 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 4794 // If the object has fast properties, check whether the first slot
4678 // in the descriptor array matches the hidden string. Since the 4795 // in the descriptor array matches the hidden string. Since the
4679 // hidden strings hash code is zero (and no other name has hash 4796 // hidden strings hash code is zero (and no other name has hash
4680 // code zero) it will always occupy the first entry if present. 4797 // code zero) it will always occupy the first entry if present.
4681 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4798 DescriptorArray* descriptors = this->map()->instance_descriptors();
4682 if (descriptors->number_of_descriptors() > 0) { 4799 if (descriptors->number_of_descriptors() > 0) {
4683 int sorted_index = descriptors->GetSortedKeyIndex(0); 4800 int sorted_index = descriptors->GetSortedKeyIndex(0);
4684 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4801 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4685 sorted_index < map()->NumberOfOwnDescriptors()) { 4802 sorted_index < map()->NumberOfOwnDescriptors()) {
4686 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4803 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4687 this->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), 4804 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value);
4688 value);
4689 return this; 4805 return this;
4690 } 4806 }
4691 } 4807 }
4692 } 4808 }
4693 MaybeObject* store_result = 4809 MaybeObject* store_result =
4694 SetPropertyPostInterceptor(GetHeap()->hidden_string(), 4810 SetPropertyPostInterceptor(GetHeap()->hidden_string(),
4695 value, 4811 value,
4696 DONT_ENUM, 4812 DONT_ENUM,
4697 kNonStrictMode, 4813 kNonStrictMode,
4698 OMIT_EXTENSIBILITY_CHECK); 4814 OMIT_EXTENSIBILITY_CHECK);
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
5154 set_map(new_map); 5270 set_map(new_map);
5155 ASSERT(!map()->is_extensible()); 5271 ASSERT(!map()->is_extensible());
5156 return new_map; 5272 return new_map;
5157 } 5273 }
5158 5274
5159 5275
5160 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { 5276 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
5161 StackLimitCheck check(isolate); 5277 StackLimitCheck check(isolate);
5162 if (check.HasOverflowed()) return isolate->StackOverflow(); 5278 if (check.HasOverflowed()) return isolate->StackOverflow();
5163 5279
5280 if (map()->is_deprecated()) {
5281 MaybeObject* maybe_failure = MigrateInstance();
5282 if (maybe_failure->IsFailure()) return maybe_failure;
5283 }
5284
5164 Heap* heap = isolate->heap(); 5285 Heap* heap = isolate->heap();
5165 Object* result; 5286 Object* result;
5166 { MaybeObject* maybe_result = heap->CopyJSObject(this); 5287 { MaybeObject* maybe_result = heap->CopyJSObject(this);
5167 if (!maybe_result->ToObject(&result)) return maybe_result; 5288 if (!maybe_result->ToObject(&result)) return maybe_result;
5168 } 5289 }
5169 JSObject* copy = JSObject::cast(result); 5290 JSObject* copy = JSObject::cast(result);
5170 5291
5171 // Deep copy local properties. 5292 // Deep copy local properties.
5172 if (copy->HasFastProperties()) { 5293 if (copy->HasFastProperties()) {
5173 FixedArray* properties = copy->properties(); 5294 DescriptorArray* descriptors = copy->map()->instance_descriptors();
5174 for (int i = 0; i < properties->length(); i++) { 5295 int limit = copy->map()->NumberOfOwnDescriptors();
5175 Object* value = properties->get(i); 5296 for (int i = 0; i < limit; i++) {
5297 PropertyDetails details = descriptors->GetDetails(i);
5298 if (details.type() != FIELD) continue;
5299 int index = descriptors->GetFieldIndex(i);
5300 Object* value = FastPropertyAt(index);
5176 if (value->IsJSObject()) { 5301 if (value->IsJSObject()) {
5177 JSObject* js_object = JSObject::cast(value); 5302 JSObject* js_object = JSObject::cast(value);
5178 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); 5303 MaybeObject* maybe_copy = js_object->DeepCopy(isolate);
5179 if (!maybe_result->ToObject(&result)) return maybe_result; 5304 if (!maybe_copy->To(&value)) return maybe_copy;
5305 } else {
5306 Representation representation = details.representation();
5307 if (representation.IsDouble()) {
5308 MaybeObject* maybe_number = heap->AllocateHeapNumber(value->Number());
danno 2013/05/07 13:04:47 NewStorageForValue
Toon Verwaest 2013/05/07 15:08:52 Done.
5309 if (!maybe_number->To(&value)) return maybe_number;
5180 } 5310 }
5181 properties->set(i, result);
5182 } 5311 }
5183 } 5312 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 } 5313 }
5195 } else { 5314 } else {
5196 { MaybeObject* maybe_result = 5315 { MaybeObject* maybe_result =
5197 heap->AllocateFixedArray(copy->NumberOfLocalProperties()); 5316 heap->AllocateFixedArray(copy->NumberOfLocalProperties());
5198 if (!maybe_result->ToObject(&result)) return maybe_result; 5317 if (!maybe_result->ToObject(&result)) return maybe_result;
5199 } 5318 }
5200 FixedArray* names = FixedArray::cast(result); 5319 FixedArray* names = FixedArray::cast(result);
5201 copy->GetLocalPropertyNames(names, 0); 5320 copy->GetLocalPropertyNames(names, 0);
5202 for (int i = 0; i < names->length(); i++) { 5321 for (int i = 0; i < names->length(); i++) {
5203 ASSERT(names->get(i)->IsString()); 5322 ASSERT(names->get(i)->IsString());
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
6011 return heap->undefined_value(); 6130 return heap->undefined_value();
6012 } 6131 }
6013 6132
6014 6133
6015 Object* JSObject::SlowReverseLookup(Object* value) { 6134 Object* JSObject::SlowReverseLookup(Object* value) {
6016 if (HasFastProperties()) { 6135 if (HasFastProperties()) {
6017 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); 6136 int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
6018 DescriptorArray* descs = map()->instance_descriptors(); 6137 DescriptorArray* descs = map()->instance_descriptors();
6019 for (int i = 0; i < number_of_own_descriptors; i++) { 6138 for (int i = 0; i < number_of_own_descriptors; i++) {
6020 if (descs->GetType(i) == FIELD) { 6139 if (descs->GetType(i) == FIELD) {
6021 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { 6140 Object* property = FastPropertyAt(descs->GetFieldIndex(i));
6141 if (FLAG_track_double_fields &&
6142 descs->GetDetails(i).representation().IsDouble()) {
6143 ASSERT(property->IsHeapNumber());
6144 if (value->IsNumber() && property->Number() == value->Number()) {
6145 return descs->GetKey(i);
6146 }
6147 } else if (property == value) {
6022 return descs->GetKey(i); 6148 return descs->GetKey(i);
6023 } 6149 }
6024 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { 6150 } else if (descs->GetType(i) == CONSTANT_FUNCTION) {
6025 if (descs->GetConstantFunction(i) == value) { 6151 if (descs->GetConstantFunction(i) == value) {
6026 return descs->GetKey(i); 6152 return descs->GetKey(i);
6027 } 6153 }
6028 } 6154 }
6029 } 6155 }
6030 return GetHeap()->undefined_value(); 6156 return GetHeap()->undefined_value();
6031 } else { 6157 } else {
(...skipping 9107 matching lines...) Expand 10 before | Expand all | Expand 10 after
15139 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 15265 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
15140 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 15266 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
15141 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 15267 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
15142 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 15268 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
15143 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 15269 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
15144 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 15270 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
15145 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 15271 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
15146 } 15272 }
15147 15273
15148 } } // namespace v8::internal 15274 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698