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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 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 |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |