OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |