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

Side by Side Diff: src/objects.cc

Issue 338793004: More set_map() calls replaced with MigrateToMap(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/factory.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698