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

Unified Diff: src/objects.cc

Issue 1697173002: [runtime] Optimize MigrateFastToFast for the transition case (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 2bf21a2c6d82a9b1191b83c1f16dc5b7401d81a5..89bc3c91c941c765ff346f068f93ce38a9044970 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2883,45 +2883,43 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
Isolate* isolate = object->GetIsolate();
Handle<Map> old_map(object->map());
- int old_number_of_fields;
- int number_of_fields = new_map->NumberOfFields();
- int inobject = new_map->GetInObjectProperties();
- int unused = new_map->unused_property_fields();
-
- // Nothing to do if no functions were converted to fields and no smis were
- // converted to doubles.
- if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
- unused, &old_number_of_fields)) {
- object->synchronized_set_map(*new_map);
- return;
- }
-
- int total_size = number_of_fields + unused;
- int external = total_size - inobject;
+ // In case of a regular transition.
+ if (new_map->GetBackPointer() == *old_map) {
+ // If the map does not add named properties, simply set the map.
+ if (old_map->NumberOfOwnDescriptors() ==
+ new_map->NumberOfOwnDescriptors()) {
+ object->synchronized_set_map(*new_map);
+ return;
+ }
- if (number_of_fields != old_number_of_fields &&
- new_map->GetBackPointer() == *old_map) {
PropertyDetails details = new_map->GetLastDescriptorDetails();
+ // Either new_map adds an kDescriptor property, or a kField property for
+ // which there is still space, and which does not require a mutable double
+ // box (an out-of-object double).
+ if (details.location() == kDescriptor ||
+ (old_map->unused_property_fields() > 0 &&
+ ((FLAG_unbox_double_fields && object->properties()->length() == 0) ||
+ !details.representation().IsDouble()))) {
+ object->synchronized_set_map(*new_map);
+ return;
+ }
+ // If there is still space in the object, we need to allocate a mutable
+ // double box.
if (old_map->unused_property_fields() > 0) {
- if (details.representation().IsDouble()) {
- FieldIndex index =
- FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
- if (new_map->IsUnboxedDoubleField(index)) {
- object->RawFastDoublePropertyAtPut(index, 0);
- } else {
- Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
- object->RawFastPropertyAtPut(index, *value);
- }
- }
+ FieldIndex index =
+ FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
+ DCHECK(details.representation().IsDouble());
+ DCHECK(!new_map->IsUnboxedDoubleField(index));
+ Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
+ object->RawFastPropertyAtPut(index, *value);
object->synchronized_set_map(*new_map);
return;
}
- DCHECK(number_of_fields == old_number_of_fields + 1);
// This migration is a transition from a map that has run out of property
- // space. Therefore it could be done by extending the backing store.
- int grow_by = external - object->properties()->length();
+ // space. Extend the backing store.
+ int grow_by = new_map->unused_property_fields() + 1;
Handle<FixedArray> old_storage = handle(object->properties(), isolate);
Handle<FixedArray> new_storage =
isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by);
@@ -2933,8 +2931,8 @@ void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
} else {
value = isolate->factory()->uninitialized_value();
}
- DCHECK(details.type() == DATA);
- int target_index = details.field_index() - inobject;
+ DCHECK_EQ(DATA, details.type());
+ int target_index = details.field_index() - new_map->GetInObjectProperties();
DCHECK(target_index >= 0); // Must be a backing store index.
new_storage->set(target_index, *value);
@@ -2946,6 +2944,23 @@ void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
object->synchronized_set_map(*new_map);
return;
}
+
+ int old_number_of_fields;
+ int number_of_fields = new_map->NumberOfFields();
+ int inobject = new_map->GetInObjectProperties();
+ int unused = new_map->unused_property_fields();
+
+ // Nothing to do if no functions were converted to fields and no smis were
+ // converted to doubles.
+ if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
+ unused, &old_number_of_fields)) {
+ object->synchronized_set_map(*new_map);
+ return;
+ }
+
+ int total_size = number_of_fields + unused;
+ int external = total_size - inobject;
+
Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698