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

Side by Side Diff: src/objects.cc

Issue 23583052: Handlify JSObject::MigrateInstance and friends. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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/objects.h ('k') | src/objects-inl.h » ('j') | 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 // 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 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 1846
1847 1847
1848 String* JSReceiver::constructor_name() { 1848 String* JSReceiver::constructor_name() {
1849 return map()->constructor_name(); 1849 return map()->constructor_name();
1850 } 1850 }
1851 1851
1852 1852
1853 // TODO(mstarzinger): Temporary wrapper until handlified. 1853 // TODO(mstarzinger): Temporary wrapper until handlified.
1854 static Handle<Object> NewStorageFor(Isolate* isolate, 1854 static Handle<Object> NewStorageFor(Isolate* isolate,
1855 Handle<Object> object, 1855 Handle<Object> object,
1856 Representation representation) { 1856 Representation representation,
1857 PretenureFlag tenure = NOT_TENURED) {
1857 Heap* heap = isolate->heap(); 1858 Heap* heap = isolate->heap();
1858 CALL_HEAP_FUNCTION(isolate, 1859 CALL_HEAP_FUNCTION(isolate,
1859 object->AllocateNewStorageFor(heap, representation), 1860 object->AllocateNewStorageFor(
1861 heap, representation, tenure),
1860 Object); 1862 Object);
1861 } 1863 }
1862 1864
1863 1865
1864 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object, 1866 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
1865 Handle<Map> new_map, 1867 Handle<Map> new_map,
1866 Handle<Name> name, 1868 Handle<Name> name,
1867 Handle<Object> value, 1869 Handle<Object> value,
1868 int field_index, 1870 int field_index,
1869 Representation representation) { 1871 Representation representation) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 ASSERT(target_inobject < inobject_properties()); 2265 ASSERT(target_inobject < inobject_properties());
2264 if (target_number_of_fields <= target_inobject) { 2266 if (target_number_of_fields <= target_inobject) {
2265 ASSERT(target_number_of_fields + target_unused == target_inobject); 2267 ASSERT(target_number_of_fields + target_unused == target_inobject);
2266 return false; 2268 return false;
2267 } 2269 }
2268 // Otherwise, properties will need to be moved to the backing store. 2270 // Otherwise, properties will need to be moved to the backing store.
2269 return true; 2271 return true;
2270 } 2272 }
2271 2273
2272 2274
2273 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2274 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map));
2275 }
2276
2277
2278 // To migrate an instance to a map: 2275 // To migrate an instance to a map:
2279 // - First check whether the instance needs to be rewritten. If not, simply 2276 // - First check whether the instance needs to be rewritten. If not, simply
2280 // change the map. 2277 // change the map.
2281 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2278 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2282 // addition to unused space. 2279 // addition to unused space.
2283 // - Copy all existing properties in, in the following order: backing store 2280 // - Copy all existing properties in, in the following order: backing store
2284 // properties, unused fields, inobject properties. 2281 // properties, unused fields, inobject properties.
2285 // - If all allocation succeeded, commit the state atomically: 2282 // - If all allocation succeeded, commit the state atomically:
2286 // * Copy inobject properties from the backing store back into the object. 2283 // * Copy inobject properties from the backing store back into the object.
2287 // * Trim the difference in instance size of the object. This also cleanly 2284 // * Trim the difference in instance size of the object. This also cleanly
2288 // frees inobject properties that moved to the backing store. 2285 // frees inobject properties that moved to the backing store.
2289 // * If there are properties left in the backing store, trim of the space used 2286 // * If there are properties left in the backing store, trim of the space used
2290 // to temporarily store the inobject properties. 2287 // to temporarily store the inobject properties.
2291 // * If there are properties left in the backing store, install the backing 2288 // * If there are properties left in the backing store, install the backing
2292 // store. 2289 // store.
2293 MaybeObject* JSObject::MigrateToMap(Map* new_map) { 2290 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2294 Heap* heap = GetHeap(); 2291 Isolate* isolate = object->GetIsolate();
2295 Map* old_map = map(); 2292 Handle<Map> old_map(object->map());
2296 int number_of_fields = new_map->NumberOfFields(); 2293 int number_of_fields = new_map->NumberOfFields();
2297 int inobject = new_map->inobject_properties(); 2294 int inobject = new_map->inobject_properties();
2298 int unused = new_map->unused_property_fields(); 2295 int unused = new_map->unused_property_fields();
2299 2296
2300 // Nothing to do if no functions were converted to fields. 2297 // Nothing to do if no functions were converted to fields.
Toon Verwaest 2013/09/19 11:41:42 and no smis were converted to doubles.
Michael Starzinger 2013/09/19 15:47:56 Done.
2301 if (!old_map->InstancesNeedRewriting( 2298 if (!old_map->InstancesNeedRewriting(
2302 new_map, number_of_fields, inobject, unused)) { 2299 *new_map, number_of_fields, inobject, unused)) {
2303 set_map(new_map); 2300 object->set_map(*new_map);
2304 return this; 2301 return;
2305 } 2302 }
2306 2303
2307 int total_size = number_of_fields + unused; 2304 int total_size = number_of_fields + unused;
2308 int external = total_size - inobject; 2305 int external = total_size - inobject;
2309 FixedArray* array; 2306 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
2310 MaybeObject* maybe_array = heap->AllocateFixedArray(total_size);
2311 if (!maybe_array->To(&array)) return maybe_array;
2312 2307
2313 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2308 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2314 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2309 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2315 int descriptors = new_map->NumberOfOwnDescriptors(); 2310 int descriptors = new_map->NumberOfOwnDescriptors();
2316 2311
2317 for (int i = 0; i < descriptors; i++) { 2312 for (int i = 0; i < descriptors; i++) {
2318 PropertyDetails details = new_descriptors->GetDetails(i); 2313 PropertyDetails details = new_descriptors->GetDetails(i);
2319 if (details.type() != FIELD) continue; 2314 if (details.type() != FIELD) continue;
2320 PropertyDetails old_details = old_descriptors->GetDetails(i); 2315 PropertyDetails old_details = old_descriptors->GetDetails(i);
2321 if (old_details.type() == CALLBACKS) { 2316 if (old_details.type() == CALLBACKS) {
2322 ASSERT(details.representation().IsTagged()); 2317 ASSERT(details.representation().IsTagged());
2323 continue; 2318 continue;
2324 } 2319 }
2325 ASSERT(old_details.type() == CONSTANT || 2320 ASSERT(old_details.type() == CONSTANT ||
2326 old_details.type() == FIELD); 2321 old_details.type() == FIELD);
2327 Object* value = old_details.type() == CONSTANT 2322 Object* raw_value = old_details.type() == CONSTANT
2328 ? old_descriptors->GetValue(i) 2323 ? old_descriptors->GetValue(i)
2329 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2324 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2325 Handle<Object> value(raw_value, isolate);
2330 if (FLAG_track_double_fields && 2326 if (FLAG_track_double_fields &&
2331 !old_details.representation().IsDouble() && 2327 !old_details.representation().IsDouble() &&
2332 details.representation().IsDouble()) { 2328 details.representation().IsDouble()) {
2333 if (old_details.representation().IsNone()) value = Smi::FromInt(0); 2329 if (old_details.representation().IsNone()) {
2330 value = handle(Smi::FromInt(0), isolate);
2331 }
2334 // Objects must be allocated in the old object space, since the 2332 // Objects must be allocated in the old object space, since the
2335 // overall number of HeapNumbers needed for the conversion might 2333 // overall number of HeapNumbers needed for the conversion might
2336 // exceed the capacity of new space, and we would fail repeatedly 2334 // exceed the capacity of new space, and we would fail repeatedly
2337 // trying to migrate the instance. 2335 // trying to migrate the instance.
Toon Verwaest 2013/09/19 11:41:42 Now that this is handlified, we don't need to pre-
Michael Starzinger 2013/09/19 15:47:56 Done.
2338 MaybeObject* maybe_storage = 2336 value = NewStorageFor(isolate, value, details.representation(), TENURED);
2339 value->AllocateNewStorageFor(heap, details.representation(), TENURED);
2340 if (!maybe_storage->To(&value)) return maybe_storage;
2341 } 2337 }
2342 ASSERT(!(FLAG_track_double_fields && 2338 ASSERT(!(FLAG_track_double_fields &&
2343 details.representation().IsDouble() && 2339 details.representation().IsDouble() &&
2344 value->IsSmi())); 2340 value->IsSmi()));
2345 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2341 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2346 if (target_index < 0) target_index += total_size; 2342 if (target_index < 0) target_index += total_size;
2347 array->set(target_index, value); 2343 array->set(target_index, *value);
2348 } 2344 }
2349 2345
2350 // From here on we cannot fail anymore. 2346 // From here on we cannot fail and we shouldn't GC anymore.
2351 2347
2352 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2348 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2353 // avoid overwriting |one_pointer_filler_map|. 2349 // avoid overwriting |one_pointer_filler_map|.
2354 int limit = Min(inobject, number_of_fields); 2350 int limit = Min(inobject, number_of_fields);
2355 for (int i = 0; i < limit; i++) { 2351 for (int i = 0; i < limit; i++) {
2356 FastPropertyAtPut(i, array->get(external + i)); 2352 object->FastPropertyAtPut(i, array->get(external + i));
2357 } 2353 }
2358 2354
2359 // Create filler object past the new instance size. 2355 // Create filler object past the new instance size.
2360 int new_instance_size = new_map->instance_size(); 2356 int new_instance_size = new_map->instance_size();
2361 int instance_size_delta = old_map->instance_size() - new_instance_size; 2357 int instance_size_delta = old_map->instance_size() - new_instance_size;
2362 ASSERT(instance_size_delta >= 0); 2358 ASSERT(instance_size_delta >= 0);
2363 Address address = this->address() + new_instance_size; 2359 Address address = object->address() + new_instance_size;
2364 heap->CreateFillerObjectAt(address, instance_size_delta); 2360 isolate->heap()->CreateFillerObjectAt(address, instance_size_delta);
2365 2361
2366 // If there are properties in the new backing store, trim it to the correct 2362 // If there are properties in the new backing store, trim it to the correct
2367 // size and install the backing store into the object. 2363 // size and install the backing store into the object.
2368 if (external > 0) { 2364 if (external > 0) {
2369 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); 2365 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject);
2370 set_properties(array); 2366 object->set_properties(*array);
2371 } 2367 }
2372 2368
2373 set_map(new_map); 2369 object->set_map(*new_map);
2374
2375 return this;
2376 } 2370 }
2377 2371
2378 2372
2379 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2373 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2380 int modify_index, 2374 int modify_index,
2381 Representation new_representation, 2375 Representation new_representation,
2382 StoreMode store_mode) { 2376 StoreMode store_mode) {
2383 Handle<Map> new_map = Map::GeneralizeRepresentation( 2377 Handle<Map> new_map = Map::GeneralizeRepresentation(
2384 handle(object->map()), modify_index, new_representation, store_mode); 2378 handle(object->map()), modify_index, new_representation, store_mode);
2385 if (object->map() == *new_map) return; 2379 if (object->map() == *new_map) return;
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 Handle<Map> original_map(object->map()); 3748 Handle<Map> original_map(object->map());
3755 GeneralizeFieldRepresentation( 3749 GeneralizeFieldRepresentation(
3756 object, 0, Representation::None(), ALLOW_AS_CONSTANT); 3750 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3757 if (FLAG_trace_migration) { 3751 if (FLAG_trace_migration) {
3758 object->PrintInstanceMigration(stdout, *original_map, object->map()); 3752 object->PrintInstanceMigration(stdout, *original_map, object->map());
3759 } 3753 }
3760 } 3754 }
3761 3755
3762 3756
3763 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3757 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3764 MigrateInstance(object); 3758 Map* new_map = object->map()->CurrentMapForDeprecated();
3759 if (new_map == NULL) return Handle<Object>();
3760 Handle<Map> original_map(object->map());
3761 JSObject::MigrateToMap(object, handle(new_map));
3762 if (FLAG_trace_migration) {
3763 object->PrintInstanceMigration(stdout, *original_map, object->map());
3764 }
3765 return object; 3765 return object;
3766 } 3766 }
3767 3767
3768 3768
3769 Handle<Object> JSObject::SetPropertyUsingTransition( 3769 Handle<Object> JSObject::SetPropertyUsingTransition(
3770 Handle<JSObject> object, 3770 Handle<JSObject> object,
3771 LookupResult* lookup, 3771 LookupResult* lookup,
3772 Handle<Name> name, 3772 Handle<Name> name,
3773 Handle<Object> value, 3773 Handle<Object> value,
3774 PropertyAttributes attributes) { 3774 PropertyAttributes attributes) {
(...skipping 12350 matching lines...) Expand 10 before | Expand all | Expand 10 after
16125 #define ERROR_MESSAGES_TEXTS(C, T) T, 16125 #define ERROR_MESSAGES_TEXTS(C, T) T,
16126 static const char* error_messages_[] = { 16126 static const char* error_messages_[] = {
16127 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16127 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16128 }; 16128 };
16129 #undef ERROR_MESSAGES_TEXTS 16129 #undef ERROR_MESSAGES_TEXTS
16130 return error_messages_[reason]; 16130 return error_messages_[reason];
16131 } 16131 }
16132 16132
16133 16133
16134 } } // namespace v8::internal 16134 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698