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

Unified Diff: src/objects.cc

Issue 231283006: Work towards unifying descriptor array handling. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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 | « src/objects.h ('k') | 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 2bf5b4a4a0bc760ba695038e247406497a9b9725..3f6560eebf543c556a7852f85c7974729687a53d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2548,8 +2548,7 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
new_map->NumberOfFields(),
attributes,
Representation::Tagged());
- d.SetSortedKeyIndex(details.pointer());
- descriptors->Set(modify_index, &d);
+ descriptors->Replace(modify_index, &d);
int unused_property_fields = new_map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
unused_property_fields += JSObject::kFieldsAdded;
@@ -3121,16 +3120,40 @@ MaybeHandle<Object> JSObject::SetPropertyViaPrototypes(
void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
+ // Only supports adding slack to owned descriptors.
+ ASSERT(map->owns_descriptors());
+
Handle<DescriptorArray> descriptors(map->instance_descriptors());
+ int old_size = map->NumberOfOwnDescriptors();
if (slack <= descriptors->NumberOfSlackDescriptors()) return;
- int number_of_descriptors = descriptors->number_of_descriptors();
- Isolate* isolate = map->GetIsolate();
- Handle<DescriptorArray> new_descriptors =
- isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
- for (int i = 0; i < number_of_descriptors; ++i) {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, old_size, slack);
+
+ if (old_size == 0) {
+ map->set_instance_descriptors(*new_descriptors);
+ return;
+ }
+
+ // If the source descriptors had an enum cache we copy it. This ensures
+ // that the maps to which we push the new descriptor array back can rely
+ // on a cache always being available once it is set. If the map has more
+ // enumerated descriptors than available in the original cache, the cache
+ // will be lazily replaced by the extended cache when needed.
+ if (descriptors->HasEnumCache()) {
+ new_descriptors->CopyEnumCacheFrom(*descriptors);
+ }
+
+ // Replace descriptors by new_descriptors in all maps that share it.
+ map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
+
+ Map* walk_map;
+ for (Object* current = map->GetBackPointer();
+ !current->IsUndefined();
+ current = walk_map->GetBackPointer()) {
+ walk_map = Map::cast(current);
+ if (walk_map->instance_descriptors() != *descriptors) break;
+ walk_map->set_instance_descriptors(*new_descriptors);
}
map->set_instance_descriptors(*new_descriptors);
@@ -6840,62 +6863,29 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
// descriptors in the descriptor array.
ASSERT(map->NumberOfOwnDescriptors() ==
map->instance_descriptors()->number_of_descriptors());
- Handle<Map> result = Map::CopyDropDescriptors(map);
+ Handle<Map> result = Map::CopyDropDescriptors(map);
Handle<Name> name = descriptor->GetKey();
-
Handle<TransitionArray> transitions =
Map::AddTransition(map, name, result, SIMPLE_TRANSITION);
- if (descriptors->NumberOfSlackDescriptors() > 0) {
- descriptors->Append(descriptor);
- result->SetBackPointer(*map);
- result->InitializeDescriptors(*descriptors);
- } else {
+ // Ensure there's space for the new descriptor in the shared descriptor array.
+ if (descriptors->NumberOfSlackDescriptors() == 0) {
int old_size = descriptors->number_of_descriptors();
- // Descriptor arrays grow by 50%.
- Handle<DescriptorArray> new_descriptors =
- map->GetIsolate()->factory()->NewDescriptorArray(
- old_size, old_size < 4 ? 1 : old_size / 2);
-
- DisallowHeapAllocation no_gc;
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
-
- // Copy the descriptors, inserting a descriptor.
- for (int i = 0; i < old_size; ++i) {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
+ if (old_size == 0) {
+ descriptors = map->GetIsolate()->factory()->NewDescriptorArray(0, 1);
+ } else {
+ Map::EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
+ descriptors = handle(map->instance_descriptors());
}
+ }
- new_descriptors->Append(descriptor, witness);
-
- if (old_size > 0) {
- // If the source descriptors had an enum cache we copy it. This ensures
- // that the maps to which we push the new descriptor array back can rely
- // on a cache always being available once it is set. If the map has more
- // enumerated descriptors than available in the original cache, the cache
- // will be lazily replaced by the extended cache when needed.
- if (descriptors->HasEnumCache()) {
- new_descriptors->CopyEnumCacheFrom(*descriptors);
- }
-
- Map* walk_map;
- // Replace descriptors by new_descriptors in all maps that share it.
-
- map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
- for (Object* current = map->GetBackPointer();
- !current->IsUndefined();
- current = walk_map->GetBackPointer()) {
- walk_map = Map::cast(current);
- if (walk_map->instance_descriptors() != *descriptors) break;
- walk_map->set_instance_descriptors(*new_descriptors);
- }
-
- map->set_instance_descriptors(*new_descriptors);
- }
+ // Commit the state atomically.
+ DisallowHeapAllocation no_gc;
- result->SetBackPointer(*map);
- result->InitializeDescriptors(*new_descriptors);
- }
+ descriptors->Append(descriptor);
+ result->SetBackPointer(*map);
+ result->InitializeDescriptors(*descriptors);
ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
@@ -7098,36 +7088,18 @@ Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
// Ensure the key is unique.
descriptor->KeyToUniqueName();
- int old_size = map->NumberOfOwnDescriptors();
- int new_size = old_size + 1;
-
if (flag == INSERT_TRANSITION &&
map->owns_descriptors() &&
map->CanHaveMoreTransitions()) {
return Map::ShareDescriptor(map, descriptors, descriptor);
}
- Handle<DescriptorArray> new_descriptors =
- map->GetIsolate()->factory()->NewDescriptorArray(old_size, 1);
-
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
-
- // Copy the descriptors, inserting a descriptor.
- for (int i = 0; i < old_size; ++i) {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
- }
-
- if (old_size != descriptors->number_of_descriptors()) {
- new_descriptors->SetNumberOfDescriptors(new_size);
- new_descriptors->Set(old_size, descriptor, witness);
- new_descriptors->Sort();
- } else {
- new_descriptors->Append(descriptor, witness);
- }
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, map->NumberOfOwnDescriptors(), 1);
+ new_descriptors->Append(descriptor);
- Handle<Name> key = descriptor->GetKey();
return Map::CopyReplaceDescriptors(
- map, new_descriptors, flag, key, SIMPLE_TRANSITION);
+ map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION);
}
@@ -7151,25 +7123,26 @@ Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
Handle<DescriptorArray> DescriptorArray::CopyUpTo(
Handle<DescriptorArray> desc,
- int enumeration_index) {
- return DescriptorArray::CopyUpToAddAttributes(desc,
- enumeration_index,
- NONE);
+ int enumeration_index,
+ int slack) {
+ return DescriptorArray::CopyUpToAddAttributes(
+ desc, enumeration_index, NONE, slack);
}
Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
Handle<DescriptorArray> desc,
int enumeration_index,
- PropertyAttributes attributes) {
- if (enumeration_index == 0) {
+ PropertyAttributes attributes,
+ int slack) {
+ if (enumeration_index + slack == 0) {
return desc->GetIsolate()->factory()->empty_descriptor_array();
}
int size = enumeration_index;
Handle<DescriptorArray> descriptors =
- desc->GetIsolate()->factory()->NewDescriptorArray(size);
+ desc->GetIsolate()->factory()->NewDescriptorArray(size, slack);
DescriptorArray::WhitenessWitness witness(*descriptors);
if (attributes != NONE) {
@@ -7190,7 +7163,7 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
}
} else {
for (int i = 0; i < size; ++i) {
- descriptors->CopyFrom(i, *desc, i, witness);
+ descriptors->CopyFrom(i, *desc, witness);
}
}
@@ -7211,24 +7184,10 @@ Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
Handle<Name> key = descriptor->GetKey();
ASSERT(*key == descriptors->GetKey(insertion_index));
- int new_size = map->NumberOfOwnDescriptors();
- ASSERT(0 <= insertion_index && insertion_index < new_size);
-
- ASSERT_LT(insertion_index, new_size);
-
- Handle<DescriptorArray> new_descriptors =
- map->GetIsolate()->factory()->NewDescriptorArray(new_size);
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
-
- for (int i = 0; i < new_size; ++i) {
- if (i == insertion_index) {
- new_descriptors->Set(i, descriptor, witness);
- } else {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
- }
- }
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, map->NumberOfOwnDescriptors());
- new_descriptors->Sort();
+ new_descriptors->Replace(insertion_index, descriptor);
SimpleTransitionFlag simple_flag =
(insertion_index == descriptors->number_of_descriptors() - 1)
@@ -8058,6 +8017,12 @@ void DescriptorArray::ClearEnumCache() {
}
+void DescriptorArray::Replace(int index, Descriptor* descriptor) {
+ descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
+ Set(index, descriptor);
+}
+
+
void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
FixedArray* new_cache,
Object* new_index_cache) {
@@ -8073,16 +8038,15 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
}
-void DescriptorArray::CopyFrom(int dst_index,
+void DescriptorArray::CopyFrom(int index,
DescriptorArray* src,
- int src_index,
const WhitenessWitness& witness) {
- Object* value = src->GetValue(src_index);
- PropertyDetails details = src->GetDetails(src_index);
- Descriptor desc(handle(src->GetKey(src_index)),
+ Object* value = src->GetValue(index);
+ PropertyDetails details = src->GetDetails(index);
+ Descriptor desc(handle(src->GetKey(index)),
handle(value, src->GetIsolate()),
details);
- Set(dst_index, &desc, witness);
+ Set(index, &desc, witness);
}
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698