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

Unified Diff: src/objects.cc

Issue 11099064: Remove descriptors pointer. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed nits Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | 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 4d8fe8eb059a0f0690f1849f071416500df6a740..1974a5de607c01df32f3fe85e3a024092389c313 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1777,13 +1777,7 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
// allocation that may fail.
if (!old_target->StoresOwnDescriptors()) {
DescriptorArray* old_descriptors = old_map->instance_descriptors();
-
- old_target->SetBackPointer(GetHeap()->undefined_value());
MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
- // Reset the backpointer before returning failure, otherwise the map ends up
- // with an undefined backpointer and no descriptors, losing its own
- // descriptors. Setting the backpointer always succeeds.
- old_target->SetBackPointer(old_map);
if (maybe_failure->IsFailure()) return maybe_failure;
}
@@ -1802,36 +1796,28 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
// invalid back pointers. This will change once we can store multiple
// transitions with the same key.
- if (old_map->owns_descriptors()) {
- // If the old map owns its own descriptors, transfer ownership to the
- // new_map and install its descriptors in the old_map. Since the old_map
- // stores the descriptors for the new_map, remove the transition array of
- // the new_map that is only in place to store the descriptors.
- old_map->transitions()->descriptors_pointer()->set_value(
- new_map->instance_descriptors());
- new_map->ClearTransitions(GetHeap());
- old_map->set_owns_descriptors(false);
- } else if (old_target->instance_descriptors() ==
- old_map->instance_descriptors()) {
+ bool owned_descriptors = old_map->owns_descriptors();
+ if (owned_descriptors ||
+ old_target->instance_descriptors() == old_map->instance_descriptors()) {
// Since the conversion above generated a new fast map with an additional
// property which can be shared as well, install this descriptor pointer
// along the entire chain of smaller maps; and remove the transition array
// that is only in place to hold the descriptor array in the new map.
Map* map;
- JSGlobalPropertyCell* new_pointer =
- new_map->transitions()->descriptors_pointer();
- JSGlobalPropertyCell* old_pointer =
- old_map->transitions()->descriptors_pointer();
+ DescriptorArray* new_descriptors = new_map->instance_descriptors();
+ DescriptorArray* old_descriptors = old_map->instance_descriptors();
for (Object* current = old_map;
!current->IsUndefined();
current = map->GetBackPointer()) {
map = Map::cast(current);
if (!map->HasTransitionArray()) break;
TransitionArray* transitions = map->transitions();
- if (transitions->descriptors_pointer() != old_pointer) break;
- map->SetEnumLength(Map::kInvalidEnumCache);
- transitions->set_descriptors_pointer(new_pointer);
+ if (transitions->descriptors() != old_descriptors) break;
+ // Invalidate the enum caches only if the map did not own its descriptors.
+ if (!owned_descriptors) map->SetEnumLength(Map::kInvalidEnumCache);
+ transitions->set_descriptors(new_descriptors);
}
+ old_map->set_owns_descriptors(false);
new_map->ClearTransitions(GetHeap());
}
@@ -4975,15 +4961,13 @@ MaybeObject* Map::CopyDropDescriptors() {
}
-MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
+MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor) {
// Sanity check. This path is only to be taken if the map owns its descriptor
// array, implying that its NumberOfOwnDescriptors equals the number of
// descriptors in the descriptor array.
- if (NumberOfOwnDescriptors() !=
- instance_descriptors()->number_of_descriptors()) {
- Isolate::Current()->PushStackTraceAndDie(
- 0xDEAD0002, GetBackPointer(), this, 0xDEAD0003);
- }
+ ASSERT(NumberOfOwnDescriptors() ==
+ instance_descriptors()->number_of_descriptors());
Map* result;
MaybeObject* maybe_result = CopyDropDescriptors();
if (!maybe_result->To(&result)) return maybe_result;
@@ -4995,7 +4979,6 @@ MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
AddTransition(name, result, SIMPLE_TRANSITION);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
- DescriptorArray* descriptors = instance_descriptors();
int old_size = descriptors->number_of_descriptors();
DescriptorArray* new_descriptors;
@@ -5026,9 +5009,21 @@ MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
if (descriptors->HasEnumCache()) {
new_descriptors->CopyEnumCacheFrom(descriptors);
}
- }
- transitions->set_descriptors(new_descriptors);
+ Map* map;
+ // Replace descriptors by new_descriptors in all maps that share it.
+ for (Object* current = GetBackPointer();
+ !current->IsUndefined();
+ current = map->GetBackPointer()) {
+ map = Map::cast(current);
+ if (!map->HasTransitionArray()) break;
+ TransitionArray* transitions = map->transitions();
+ if (transitions->descriptors() != descriptors) break;
+ transitions->set_descriptors(new_descriptors);
+ }
+
+ transitions->set_descriptors(new_descriptors);
+ }
set_transitions(transitions);
result->SetBackPointer(this);
@@ -5073,7 +5068,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
// If the copied map has no added fields, and the parent map owns its
// descriptors, those descriptors have to be empty. In that case,
// transfer ownership of the descriptors to the new child.
- CHECK(instance_descriptors()->IsEmpty());
+ ASSERT(instance_descriptors()->IsEmpty());
set_owns_descriptors(false);
} else {
// If the parent did not own its own descriptors, it may share a larger
@@ -5201,7 +5196,7 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
if (flag == INSERT_TRANSITION &&
owns_descriptors() &&
CanHaveMoreTransitions()) {
- return ShareDescriptor(descriptor);
+ return ShareDescriptor(descriptors, descriptor);
}
DescriptorArray* new_descriptors;
@@ -5241,7 +5236,7 @@ MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
// We replace the key if it is already present.
int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
if (index != DescriptorArray::kNotFound) {
- return CopyReplaceDescriptor(descriptor, index, flag);
+ return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
}
return CopyAddDescriptor(descriptor, flag);
}
@@ -5267,15 +5262,14 @@ MaybeObject* DescriptorArray::CopyUpTo(int enumeration_index) {
}
-MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor,
+MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor,
int insertion_index,
TransitionFlag flag) {
// Ensure the key is a symbol.
MaybeObject* maybe_failure = descriptor->KeyToSymbol();
if (maybe_failure->IsFailure()) return maybe_failure;
- DescriptorArray* descriptors = instance_descriptors();
-
String* key = descriptor->GetKey();
ASSERT(key == descriptors->GetKey(insertion_index));
@@ -7458,17 +7452,7 @@ static void TrimDescriptorArray(Heap* heap,
int to_trim = number_of_descriptors - number_of_own_descriptors;
if (to_trim <= 0) return;
- // Maximally keep 50% of unused descriptors.
- int keep = Min(to_trim, number_of_own_descriptors / 2);
- for (int i = number_of_own_descriptors;
- i < number_of_own_descriptors + keep;
- ++i) {
- descriptors->EraseDescriptor(heap, i);
- }
-
- if (to_trim > keep) {
- RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep);
- }
+ RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim);
descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
@@ -7546,7 +7530,6 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
} else {
t->set_descriptors(heap->empty_descriptor_array());
}
- set_owns_descriptors(true);
}
int trim = t->number_of_transitions() - transition_index;
« 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