Chromium Code Reviews| 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 |