| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 if (object->IsGlobalObject()) { | 754 if (object->IsGlobalObject()) { |
| 755 PropertyDetails details = dictionary->DetailsAt(entry); | 755 PropertyDetails details = dictionary->DetailsAt(entry); |
| 756 if (details.IsDontDelete()) { | 756 if (details.IsDontDelete()) { |
| 757 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 757 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
| 758 // When forced to delete global properties, we have to make a | 758 // When forced to delete global properties, we have to make a |
| 759 // map change to invalidate any ICs that think they can load | 759 // map change to invalidate any ICs that think they can load |
| 760 // from the DontDelete cell without checking if it contains | 760 // from the DontDelete cell without checking if it contains |
| 761 // the hole value. | 761 // the hole value. |
| 762 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 762 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 763 ASSERT(new_map->is_dictionary_map()); | 763 ASSERT(new_map->is_dictionary_map()); |
| 764 object->set_map(*new_map); | 764 JSObject::MigrateToMap(object, new_map); |
| 765 } | 765 } |
| 766 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 766 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 767 Handle<Object> value = isolate->factory()->the_hole_value(); | 767 Handle<Object> value = isolate->factory()->the_hole_value(); |
| 768 PropertyCell::SetValueInferType(cell, value); | 768 PropertyCell::SetValueInferType(cell, value); |
| 769 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 769 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 770 } else { | 770 } else { |
| 771 Handle<Object> deleted( | 771 Handle<Object> deleted( |
| 772 NameDictionary::DeleteProperty(dictionary, entry, mode)); | 772 NameDictionary::DeleteProperty(dictionary, entry, mode)); |
| 773 if (*deleted == isolate->heap()->true_value()) { | 773 if (*deleted == isolate->heap()->true_value()) { |
| 774 Handle<NameDictionary> new_properties = | 774 Handle<NameDictionary> new_properties = |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 Isolate* isolate = object->GetIsolate(); | 2138 Isolate* isolate = object->GetIsolate(); |
| 2139 Handle<Map> old_map(object->map()); | 2139 Handle<Map> old_map(object->map()); |
| 2140 int number_of_fields = new_map->NumberOfFields(); | 2140 int number_of_fields = new_map->NumberOfFields(); |
| 2141 int inobject = new_map->inobject_properties(); | 2141 int inobject = new_map->inobject_properties(); |
| 2142 int unused = new_map->unused_property_fields(); | 2142 int unused = new_map->unused_property_fields(); |
| 2143 | 2143 |
| 2144 // Nothing to do if no functions were converted to fields and no smis were | 2144 // Nothing to do if no functions were converted to fields and no smis were |
| 2145 // converted to doubles. | 2145 // converted to doubles. |
| 2146 if (!old_map->InstancesNeedRewriting( | 2146 if (!old_map->InstancesNeedRewriting( |
| 2147 *new_map, number_of_fields, inobject, unused)) { | 2147 *new_map, number_of_fields, inobject, unused)) { |
| 2148 // Writing the new map here does not require synchronization since it does | |
| 2149 // not change the actual object size. | |
| 2150 object->synchronized_set_map(*new_map); | 2148 object->synchronized_set_map(*new_map); |
| 2151 return; | 2149 return; |
| 2152 } | 2150 } |
| 2153 | 2151 |
| 2154 int total_size = number_of_fields + unused; | 2152 int total_size = number_of_fields + unused; |
| 2155 int external = total_size - inobject; | 2153 int external = total_size - inobject; |
| 2156 | 2154 |
| 2157 if ((old_map->unused_property_fields() == 0) && | 2155 if ((old_map->unused_property_fields() == 0) && |
| 2158 (new_map->GetBackPointer() == *old_map)) { | 2156 (new_map->GetBackPointer() == *old_map)) { |
| 2159 // This migration is a transition from a map that has run out out property | 2157 // This migration is a transition from a map that has run out out property |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2173 ASSERT(details.type() == FIELD); | 2171 ASSERT(details.type() == FIELD); |
| 2174 int target_index = details.field_index() - inobject; | 2172 int target_index = details.field_index() - inobject; |
| 2175 ASSERT(target_index >= 0); // Must be a backing store index. | 2173 ASSERT(target_index >= 0); // Must be a backing store index. |
| 2176 new_storage->set(target_index, *value); | 2174 new_storage->set(target_index, *value); |
| 2177 | 2175 |
| 2178 // From here on we cannot fail and we shouldn't GC anymore. | 2176 // From here on we cannot fail and we shouldn't GC anymore. |
| 2179 DisallowHeapAllocation no_allocation; | 2177 DisallowHeapAllocation no_allocation; |
| 2180 | 2178 |
| 2181 // Set the new property value and do the map transition. | 2179 // Set the new property value and do the map transition. |
| 2182 object->set_properties(*new_storage); | 2180 object->set_properties(*new_storage); |
| 2183 // Writing the new map here does not require synchronization since it does | 2181 object->synchronized_set_map(*new_map); |
| 2184 // not change the actual object size. | |
| 2185 object->set_map(*new_map); | |
| 2186 return; | 2182 return; |
| 2187 } | 2183 } |
| 2188 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); | 2184 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); |
| 2189 | 2185 |
| 2190 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 2186 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
| 2191 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); | 2187 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); |
| 2192 int old_nof = old_map->NumberOfOwnDescriptors(); | 2188 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 2193 int new_nof = new_map->NumberOfOwnDescriptors(); | 2189 int new_nof = new_map->NumberOfOwnDescriptors(); |
| 2194 | 2190 |
| 2195 // This method only supports generalizing instances to at least the same | 2191 // This method only supports generalizing instances to at least the same |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2247 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); | 2243 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); |
| 2248 object->FastPropertyAtPut(index, array->get(external + i)); | 2244 object->FastPropertyAtPut(index, array->get(external + i)); |
| 2249 } | 2245 } |
| 2250 | 2246 |
| 2251 // Create filler object past the new instance size. | 2247 // Create filler object past the new instance size. |
| 2252 int new_instance_size = new_map->instance_size(); | 2248 int new_instance_size = new_map->instance_size(); |
| 2253 int instance_size_delta = old_map->instance_size() - new_instance_size; | 2249 int instance_size_delta = old_map->instance_size() - new_instance_size; |
| 2254 ASSERT(instance_size_delta >= 0); | 2250 ASSERT(instance_size_delta >= 0); |
| 2255 Address address = object->address() + new_instance_size; | 2251 Address address = object->address() + new_instance_size; |
| 2256 | 2252 |
| 2257 // The trimming is performed on a newly allocated object, which is on a | 2253 Heap* heap = isolate->heap(); |
| 2258 // freshly allocated page or on an already swept page. Hence, the sweeper | |
| 2259 // thread can not get confused with the filler creation. No synchronization | |
| 2260 // needed. | |
| 2261 isolate->heap()->CreateFillerObjectAt(address, instance_size_delta); | |
| 2262 | 2254 |
| 2263 // If there are properties in the new backing store, trim it to the correct | 2255 // If there are properties in the new backing store, trim it to the correct |
| 2264 // size and install the backing store into the object. | 2256 // size and install the backing store into the object. |
| 2265 if (external > 0) { | 2257 if (external > 0) { |
| 2266 RightTrimFixedArray<Heap::FROM_MUTATOR>(isolate->heap(), *array, inobject); | 2258 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); |
| 2267 object->set_properties(*array); | 2259 object->set_properties(*array); |
| 2268 } | 2260 } |
| 2269 | 2261 |
| 2270 // The trimming is performed on a newly allocated object, which is on a | 2262 heap->CreateFillerObjectAt(address, instance_size_delta); |
| 2271 // freshly allocated page or on an already swept page. Hence, the sweeper | 2263 heap->AdjustLiveBytes(address, -instance_size_delta, Heap::FROM_MUTATOR); |
| 2272 // thread can not get confused with the filler creation. No synchronization | 2264 |
| 2273 // needed. | 2265 // We are storing the new map using release store after creating a filler for |
| 2274 object->set_map(*new_map); | 2266 // the left-over space to avoid races with the sweeper thread. |
| 2267 object->synchronized_set_map(*new_map); |
| 2275 } | 2268 } |
| 2276 | 2269 |
| 2277 | 2270 |
| 2278 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2271 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
| 2279 int modify_index, | 2272 int modify_index, |
| 2280 Representation new_representation, | 2273 Representation new_representation, |
| 2281 Handle<HeapType> new_field_type, | 2274 Handle<HeapType> new_field_type, |
| 2282 StoreMode store_mode) { | 2275 StoreMode store_mode) { |
| 2283 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2276 Handle<Map> new_map = Map::GeneralizeRepresentation( |
| 2284 handle(object->map()), modify_index, new_representation, | 2277 handle(object->map()), modify_index, new_representation, |
| (...skipping 2426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4711 | 4704 |
| 4712 // Allocate new map. | 4705 // Allocate new map. |
| 4713 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 4706 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 4714 new_map->set_dictionary_map(false); | 4707 new_map->set_dictionary_map(false); |
| 4715 | 4708 |
| 4716 if (instance_descriptor_length == 0) { | 4709 if (instance_descriptor_length == 0) { |
| 4717 DisallowHeapAllocation no_gc; | 4710 DisallowHeapAllocation no_gc; |
| 4718 ASSERT_LE(unused_property_fields, inobject_props); | 4711 ASSERT_LE(unused_property_fields, inobject_props); |
| 4719 // Transform the object. | 4712 // Transform the object. |
| 4720 new_map->set_unused_property_fields(inobject_props); | 4713 new_map->set_unused_property_fields(inobject_props); |
| 4721 object->set_map(*new_map); | 4714 object->synchronized_set_map(*new_map); |
| 4722 object->set_properties(isolate->heap()->empty_fixed_array()); | 4715 object->set_properties(isolate->heap()->empty_fixed_array()); |
| 4723 // Check that it really works. | 4716 // Check that it really works. |
| 4724 ASSERT(object->HasFastProperties()); | 4717 ASSERT(object->HasFastProperties()); |
| 4725 return; | 4718 return; |
| 4726 } | 4719 } |
| 4727 | 4720 |
| 4728 // Allocate the instance descriptor. | 4721 // Allocate the instance descriptor. |
| 4729 Handle<DescriptorArray> descriptors = DescriptorArray::Allocate( | 4722 Handle<DescriptorArray> descriptors = DescriptorArray::Allocate( |
| 4730 isolate, instance_descriptor_length); | 4723 isolate, instance_descriptor_length); |
| 4731 | 4724 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4792 } | 4785 } |
| 4793 ASSERT(current_offset == number_of_fields); | 4786 ASSERT(current_offset == number_of_fields); |
| 4794 | 4787 |
| 4795 descriptors->Sort(); | 4788 descriptors->Sort(); |
| 4796 | 4789 |
| 4797 DisallowHeapAllocation no_gc; | 4790 DisallowHeapAllocation no_gc; |
| 4798 new_map->InitializeDescriptors(*descriptors); | 4791 new_map->InitializeDescriptors(*descriptors); |
| 4799 new_map->set_unused_property_fields(unused_property_fields); | 4792 new_map->set_unused_property_fields(unused_property_fields); |
| 4800 | 4793 |
| 4801 // Transform the object. | 4794 // Transform the object. |
| 4802 object->set_map(*new_map); | 4795 object->synchronized_set_map(*new_map); |
| 4803 | 4796 |
| 4804 object->set_properties(*fields); | 4797 object->set_properties(*fields); |
| 4805 ASSERT(object->IsJSObject()); | 4798 ASSERT(object->IsJSObject()); |
| 4806 | 4799 |
| 4807 // Check that it really works. | 4800 // Check that it really works. |
| 4808 ASSERT(object->HasFastProperties()); | 4801 ASSERT(object->HasFastProperties()); |
| 4809 } | 4802 } |
| 4810 | 4803 |
| 4811 | 4804 |
| 4812 void JSObject::ResetElements(Handle<JSObject> object) { | 4805 void JSObject::ResetElements(Handle<JSObject> object) { |
| (...skipping 1821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6634 Handle<Object> structure, | 6627 Handle<Object> structure, |
| 6635 PropertyAttributes attributes) { | 6628 PropertyAttributes attributes) { |
| 6636 // Normalize object to make this operation simple. | 6629 // Normalize object to make this operation simple. |
| 6637 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 6630 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 6638 | 6631 |
| 6639 // For the global object allocate a new map to invalidate the global inline | 6632 // For the global object allocate a new map to invalidate the global inline |
| 6640 // caches which have a global property cell reference directly in the code. | 6633 // caches which have a global property cell reference directly in the code. |
| 6641 if (object->IsGlobalObject()) { | 6634 if (object->IsGlobalObject()) { |
| 6642 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 6635 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 6643 ASSERT(new_map->is_dictionary_map()); | 6636 ASSERT(new_map->is_dictionary_map()); |
| 6644 object->set_map(*new_map); | 6637 JSObject::MigrateToMap(object, new_map); |
| 6645 | 6638 |
| 6646 // When running crankshaft, changing the map is not enough. We | 6639 // When running crankshaft, changing the map is not enough. We |
| 6647 // need to deoptimize all functions that rely on this global | 6640 // need to deoptimize all functions that rely on this global |
| 6648 // object. | 6641 // object. |
| 6649 Deoptimizer::DeoptimizeGlobalObject(*object); | 6642 Deoptimizer::DeoptimizeGlobalObject(*object); |
| 6650 } | 6643 } |
| 6651 | 6644 |
| 6652 // Update the dictionary with the new CALLBACKS property. | 6645 // Update the dictionary with the new CALLBACKS property. |
| 6653 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6646 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
| 6654 SetNormalizedProperty(object, name, structure, details); | 6647 SetNormalizedProperty(object, name, structure, details); |
| (...skipping 10335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16990 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16983 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16991 static const char* error_messages_[] = { | 16984 static const char* error_messages_[] = { |
| 16992 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16985 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16993 }; | 16986 }; |
| 16994 #undef ERROR_MESSAGES_TEXTS | 16987 #undef ERROR_MESSAGES_TEXTS |
| 16995 return error_messages_[reason]; | 16988 return error_messages_[reason]; |
| 16996 } | 16989 } |
| 16997 | 16990 |
| 16998 | 16991 |
| 16999 } } // namespace v8::internal | 16992 } } // namespace v8::internal |
| OLD | NEW |