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

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: Addressed comment from other CL. Created 7 years, 2 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 2252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 ASSERT(target_inobject < inobject_properties()); 2263 ASSERT(target_inobject < inobject_properties());
2264 if (target_number_of_fields <= target_inobject) { 2264 if (target_number_of_fields <= target_inobject) {
2265 ASSERT(target_number_of_fields + target_unused == target_inobject); 2265 ASSERT(target_number_of_fields + target_unused == target_inobject);
2266 return false; 2266 return false;
2267 } 2267 }
2268 // Otherwise, properties will need to be moved to the backing store. 2268 // Otherwise, properties will need to be moved to the backing store.
2269 return true; 2269 return true;
2270 } 2270 }
2271 2271
2272 2272
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: 2273 // To migrate an instance to a map:
2279 // - First check whether the instance needs to be rewritten. If not, simply 2274 // - First check whether the instance needs to be rewritten. If not, simply
2280 // change the map. 2275 // change the map.
2281 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2276 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2282 // addition to unused space. 2277 // addition to unused space.
2283 // - Copy all existing properties in, in the following order: backing store 2278 // - Copy all existing properties in, in the following order: backing store
2284 // properties, unused fields, inobject properties. 2279 // properties, unused fields, inobject properties.
2285 // - If all allocation succeeded, commit the state atomically: 2280 // - If all allocation succeeded, commit the state atomically:
2286 // * Copy inobject properties from the backing store back into the object. 2281 // * Copy inobject properties from the backing store back into the object.
2287 // * Trim the difference in instance size of the object. This also cleanly 2282 // * Trim the difference in instance size of the object. This also cleanly
2288 // frees inobject properties that moved to the backing store. 2283 // frees inobject properties that moved to the backing store.
2289 // * If there are properties left in the backing store, trim of the space used 2284 // * If there are properties left in the backing store, trim of the space used
2290 // to temporarily store the inobject properties. 2285 // to temporarily store the inobject properties.
2291 // * If there are properties left in the backing store, install the backing 2286 // * If there are properties left in the backing store, install the backing
2292 // store. 2287 // store.
2293 MaybeObject* JSObject::MigrateToMap(Map* new_map) { 2288 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2294 Heap* heap = GetHeap(); 2289 Isolate* isolate = object->GetIsolate();
2295 Map* old_map = map(); 2290 Handle<Map> old_map(object->map());
2296 int number_of_fields = new_map->NumberOfFields(); 2291 int number_of_fields = new_map->NumberOfFields();
2297 int inobject = new_map->inobject_properties(); 2292 int inobject = new_map->inobject_properties();
2298 int unused = new_map->unused_property_fields(); 2293 int unused = new_map->unused_property_fields();
2299 2294
2300 // Nothing to do if no functions were converted to fields. 2295 // Nothing to do if no functions were converted to fields and no smis were
2296 // converted to doubles.
2301 if (!old_map->InstancesNeedRewriting( 2297 if (!old_map->InstancesNeedRewriting(
2302 new_map, number_of_fields, inobject, unused)) { 2298 *new_map, number_of_fields, inobject, unused)) {
2303 set_map(new_map); 2299 object->set_map(*new_map);
2304 return this; 2300 return;
2305 } 2301 }
2306 2302
2307 int total_size = number_of_fields + unused; 2303 int total_size = number_of_fields + unused;
2308 int external = total_size - inobject; 2304 int external = total_size - inobject;
2309 FixedArray* array; 2305 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 2306
2313 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2307 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2314 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2308 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2315 int descriptors = new_map->NumberOfOwnDescriptors(); 2309 int descriptors = new_map->NumberOfOwnDescriptors();
2316 2310
2317 for (int i = 0; i < descriptors; i++) { 2311 for (int i = 0; i < descriptors; i++) {
2318 PropertyDetails details = new_descriptors->GetDetails(i); 2312 PropertyDetails details = new_descriptors->GetDetails(i);
2319 if (details.type() != FIELD) continue; 2313 if (details.type() != FIELD) continue;
2320 PropertyDetails old_details = old_descriptors->GetDetails(i); 2314 PropertyDetails old_details = old_descriptors->GetDetails(i);
2321 if (old_details.type() == CALLBACKS) { 2315 if (old_details.type() == CALLBACKS) {
2322 ASSERT(details.representation().IsTagged()); 2316 ASSERT(details.representation().IsTagged());
2323 continue; 2317 continue;
2324 } 2318 }
2325 ASSERT(old_details.type() == CONSTANT || 2319 ASSERT(old_details.type() == CONSTANT ||
2326 old_details.type() == FIELD); 2320 old_details.type() == FIELD);
2327 Object* value = old_details.type() == CONSTANT 2321 Object* raw_value = old_details.type() == CONSTANT
2328 ? old_descriptors->GetValue(i) 2322 ? old_descriptors->GetValue(i)
2329 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2323 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2324 Handle<Object> value(raw_value, isolate);
2330 if (FLAG_track_double_fields && 2325 if (FLAG_track_double_fields &&
2331 !old_details.representation().IsDouble() && 2326 !old_details.representation().IsDouble() &&
2332 details.representation().IsDouble()) { 2327 details.representation().IsDouble()) {
2333 if (old_details.representation().IsNone()) value = Smi::FromInt(0); 2328 if (old_details.representation().IsNone()) {
2334 // Objects must be allocated in the old object space, since the 2329 value = handle(Smi::FromInt(0), isolate);
2335 // overall number of HeapNumbers needed for the conversion might 2330 }
2336 // exceed the capacity of new space, and we would fail repeatedly 2331 value = NewStorageFor(isolate, value, details.representation());
2337 // trying to migrate the instance.
2338 MaybeObject* maybe_storage =
2339 value->AllocateNewStorageFor(heap, details.representation(), TENURED);
2340 if (!maybe_storage->To(&value)) return maybe_storage;
2341 } 2332 }
2342 ASSERT(!(FLAG_track_double_fields && 2333 ASSERT(!(FLAG_track_double_fields &&
2343 details.representation().IsDouble() && 2334 details.representation().IsDouble() &&
2344 value->IsSmi())); 2335 value->IsSmi()));
2345 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2336 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2346 if (target_index < 0) target_index += total_size; 2337 if (target_index < 0) target_index += total_size;
2347 array->set(target_index, value); 2338 array->set(target_index, *value);
2348 } 2339 }
2349 2340
2350 // From here on we cannot fail anymore. 2341 // From here on we cannot fail and we shouldn't GC anymore.
2342 DisallowHeapAllocation no_allocation;
2351 2343
2352 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2344 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2353 // avoid overwriting |one_pointer_filler_map|. 2345 // avoid overwriting |one_pointer_filler_map|.
2354 int limit = Min(inobject, number_of_fields); 2346 int limit = Min(inobject, number_of_fields);
2355 for (int i = 0; i < limit; i++) { 2347 for (int i = 0; i < limit; i++) {
2356 FastPropertyAtPut(i, array->get(external + i)); 2348 object->FastPropertyAtPut(i, array->get(external + i));
2357 } 2349 }
2358 2350
2359 // Create filler object past the new instance size. 2351 // Create filler object past the new instance size.
2360 int new_instance_size = new_map->instance_size(); 2352 int new_instance_size = new_map->instance_size();
2361 int instance_size_delta = old_map->instance_size() - new_instance_size; 2353 int instance_size_delta = old_map->instance_size() - new_instance_size;
2362 ASSERT(instance_size_delta >= 0); 2354 ASSERT(instance_size_delta >= 0);
2363 Address address = this->address() + new_instance_size; 2355 Address address = object->address() + new_instance_size;
2364 heap->CreateFillerObjectAt(address, instance_size_delta); 2356 isolate->heap()->CreateFillerObjectAt(address, instance_size_delta);
2365 2357
2366 // If there are properties in the new backing store, trim it to the correct 2358 // If there are properties in the new backing store, trim it to the correct
2367 // size and install the backing store into the object. 2359 // size and install the backing store into the object.
2368 if (external > 0) { 2360 if (external > 0) {
2369 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); 2361 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject);
2370 set_properties(array); 2362 object->set_properties(*array);
2371 } 2363 }
2372 2364
2373 set_map(new_map); 2365 object->set_map(*new_map);
2374
2375 return this;
2376 } 2366 }
2377 2367
2378 2368
2379 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2369 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2380 int modify_index, 2370 int modify_index,
2381 Representation new_representation, 2371 Representation new_representation,
2382 StoreMode store_mode) { 2372 StoreMode store_mode) {
2383 Handle<Map> new_map = Map::GeneralizeRepresentation( 2373 Handle<Map> new_map = Map::GeneralizeRepresentation(
2384 handle(object->map()), modify_index, new_representation, store_mode); 2374 handle(object->map()), modify_index, new_representation, store_mode);
2385 if (object->map() == *new_map) return; 2375 if (object->map() == *new_map) return;
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
3751 Handle<Map> original_map(object->map()); 3741 Handle<Map> original_map(object->map());
3752 GeneralizeFieldRepresentation( 3742 GeneralizeFieldRepresentation(
3753 object, 0, Representation::None(), ALLOW_AS_CONSTANT); 3743 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3754 if (FLAG_trace_migration) { 3744 if (FLAG_trace_migration) {
3755 object->PrintInstanceMigration(stdout, *original_map, object->map()); 3745 object->PrintInstanceMigration(stdout, *original_map, object->map());
3756 } 3746 }
3757 } 3747 }
3758 3748
3759 3749
3760 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3750 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3761 MigrateInstance(object); 3751 Map* new_map = object->map()->CurrentMapForDeprecated();
3752 if (new_map == NULL) return Handle<Object>();
3753 Handle<Map> original_map(object->map());
3754 JSObject::MigrateToMap(object, handle(new_map));
3755 if (FLAG_trace_migration) {
3756 object->PrintInstanceMigration(stdout, *original_map, object->map());
3757 }
3762 return object; 3758 return object;
3763 } 3759 }
3764 3760
3765 3761
3766 Handle<Object> JSObject::SetPropertyUsingTransition( 3762 Handle<Object> JSObject::SetPropertyUsingTransition(
3767 Handle<JSObject> object, 3763 Handle<JSObject> object,
3768 LookupResult* lookup, 3764 LookupResult* lookup,
3769 Handle<Name> name, 3765 Handle<Name> name,
3770 Handle<Object> value, 3766 Handle<Object> value,
3771 PropertyAttributes attributes) { 3767 PropertyAttributes attributes) {
(...skipping 12334 matching lines...) Expand 10 before | Expand all | Expand 10 after
16106 #define ERROR_MESSAGES_TEXTS(C, T) T, 16102 #define ERROR_MESSAGES_TEXTS(C, T) T,
16107 static const char* error_messages_[] = { 16103 static const char* error_messages_[] = {
16108 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16104 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16109 }; 16105 };
16110 #undef ERROR_MESSAGES_TEXTS 16106 #undef ERROR_MESSAGES_TEXTS
16111 return error_messages_[reason]; 16107 return error_messages_[reason];
16112 } 16108 }
16113 16109
16114 16110
16115 } } // namespace v8::internal 16111 } } // 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