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

Unified Diff: src/objects.cc

Issue 10816005: Swapped transition array and descriptor array. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments, and updated additional code comments. Created 8 years, 4 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
« src/bootstrapper.cc ('K') | « 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 46e691a73553117cd1e4f13c40563f42706266a7..765d4d06f4e86a92a6f251f475685ef0647ae6a5 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2191,7 +2191,7 @@ void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
// After this point the GC is not allowed to run anymore until the map is in a
// consistent state again, i.e., all the descriptors are appended and the
// descriptor array is trimmed to the right size.
- map->set_instance_descriptors(*result);
+ Map::SetDescriptors(map, result);
// Fill in new callback descriptors. Process the callbacks from
// back to front so that the last callback with a given name takes
@@ -2210,7 +2210,7 @@ void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
int new_number_of_descriptors = map->NumberOfSetDescriptors();
// Reinstall the original descriptor array if no new elements were added.
if (new_number_of_descriptors == descriptor_count) {
- map->set_instance_descriptors(*array);
+ Map::SetDescriptors(map, array);
return;
}
@@ -4102,7 +4102,7 @@ MaybeObject* JSObject::PreventExtensions() {
// Do a map transition, other objects with this map may still
// be extensible.
Map* new_map;
- MaybeObject* maybe = map()->Copy(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe = map()->Copy();
if (!maybe->To(&new_map)) return maybe;
new_map->set_is_extensible(false);
@@ -4139,6 +4139,13 @@ bool JSReceiver::IsSimpleEnum() {
}
+void Map::SetDescriptors(Handle<Map> map,
+ Handle<DescriptorArray> descriptors) {
+ Isolate* isolate = map->GetIsolate();
+ CALL_HEAP_FUNCTION_VOID(isolate, map->SetDescriptors(*descriptors));
+}
+
+
int Map::NumberOfDescribedProperties(PropertyAttributes filter) {
int result = 0;
DescriptorArray* descs = instance_descriptors();
@@ -4877,7 +4884,8 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
} else {
ASSERT(descriptors->GetDetails(last_added).index() ==
descriptors->number_of_descriptors());
- result->set_instance_descriptors(descriptors);
+ MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
+ if (maybe_failure->IsFailure()) return maybe_failure;
result->SetLastAdded(last_added);
}
@@ -4886,9 +4894,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
MaybeObject* maybe_transitions = AddTransition(name, result);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
- MaybeObject* maybe_set = set_transitions(transitions);
- if (maybe_set->IsFailure()) return maybe_set;
-
+ set_transitions(transitions);
result->SetBackPointer(this);
}
@@ -4899,7 +4905,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
// Create a new free-floating map only if we are not allowed to store it.
Map* new_map = NULL;
- MaybeObject* maybe_new_map = Copy(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_new_map = Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
new_map->set_elements_kind(kind);
@@ -4931,25 +4937,17 @@ MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
// array describing these properties.
ASSERT(constructor()->IsJSFunction());
JSFunction* ctor = JSFunction::cast(constructor());
- Map* initial_map = ctor->initial_map();
- DescriptorArray* initial_descriptors = initial_map->instance_descriptors();
- DescriptorArray* descriptors;
- MaybeObject* maybe_descriptors =
- initial_descriptors->Copy(DescriptorArray::MAY_BE_SHARED);
- if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
+ Map* map = ctor->initial_map();
+ DescriptorArray* descriptors = map->instance_descriptors();
- int last_added = initial_map->LastAdded();
+ int last_added = map->LastAdded();
return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
}
-MaybeObject* Map::Copy(DescriptorArray::SharedMode shared_mode) {
- DescriptorArray* source_descriptors = instance_descriptors();
- DescriptorArray* descriptors;
- MaybeObject* maybe_descriptors = source_descriptors->Copy(shared_mode);
- if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
-
+MaybeObject* Map::Copy() {
+ DescriptorArray* descriptors = instance_descriptors();
int last_added = LastAdded();
return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION);
@@ -4976,8 +4974,7 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
int new_size = old_size + 1;
DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(new_size, DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(new_size);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
FixedArray::WhitenessWitness witness(new_descriptors);
@@ -5038,8 +5035,7 @@ MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor,
ASSERT(key == descriptors->GetKey(insertion_index));
DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(size, DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_descriptors = DescriptorArray::Allocate(size);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
FixedArray::WhitenessWitness witness(new_descriptors);
@@ -5260,26 +5256,28 @@ class TraversableMap : public Map {
// If we have an unvisited child map, return that one and advance. If we have
// none, return NULL and reset any destroyed FixedArray maps.
TraversableMap* ChildIteratorNext() {
- if (HasTransitionArray()) {
- TransitionArray* transition_array = unchecked_transition_array();
-
- if (transition_array->HasPrototypeTransitions()) {
- HeapObject* proto_transitions =
- transition_array->UncheckedPrototypeTransitions();
- IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
- if (proto_iterator.IsIterating()) {
- Map* next = proto_iterator.Next();
- if (next != NULL) return static_cast<TraversableMap*>(next);
- }
- }
+ TransitionArray* transition_array = unchecked_transition_array();
+ if (!transition_array->map()->IsSmi() &&
+ !transition_array->IsTransitionArray()) {
+ return NULL;
+ }
- IntrusiveMapTransitionIterator transition_iterator(transition_array);
- if (transition_iterator.IsIterating()) {
- Map* next = transition_iterator.Next();
+ if (transition_array->HasPrototypeTransitions()) {
+ HeapObject* proto_transitions =
+ transition_array->UncheckedPrototypeTransitions();
+ IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
+ if (proto_iterator.IsIterating()) {
+ Map* next = proto_iterator.Next();
if (next != NULL) return static_cast<TraversableMap*>(next);
}
}
+ IntrusiveMapTransitionIterator transition_iterator(transition_array);
+ if (transition_iterator.IsIterating()) {
+ Map* next = transition_iterator.Next();
+ if (next != NULL) return static_cast<TraversableMap*>(next);
+ }
+
return NULL;
}
};
@@ -5829,21 +5827,17 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
#endif
-MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
- SharedMode shared_mode) {
+MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
Heap* heap = Isolate::Current()->heap();
// Do not use DescriptorArray::cast on incomplete object.
FixedArray* result;
- if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) {
- return heap->empty_descriptor_array();
- }
+ if (number_of_descriptors == 0) return heap->empty_descriptor_array();
// Allocate the array of keys.
MaybeObject* maybe_array =
heap->AllocateFixedArray(LengthFor(number_of_descriptors));
if (!maybe_array->To(&result)) return maybe_array;
result->set(kEnumCacheIndex, Smi::FromInt(0));
- result->set(kTransitionsIndex, Smi::FromInt(0));
return result;
}
@@ -5880,25 +5874,6 @@ void DescriptorArray::CopyFrom(int dst_index,
}
-MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) {
- // Allocate the new descriptor array.
- int number_of_descriptors = this->number_of_descriptors();
- DescriptorArray* new_descriptors;
- MaybeObject* maybe_result = Allocate(number_of_descriptors, shared_mode);
- if (!maybe_result->To(&new_descriptors)) return maybe_result;
-
- // Copy the content.
- if (number_of_descriptors > 0) {
- FixedArray::WhitenessWitness witness(new_descriptors);
- for (int i = 0; i < number_of_descriptors; i++) {
- new_descriptors->CopyFrom(i, this, i, witness);
- }
- }
-
- return new_descriptors;
-}
-
-
// We need the whiteness witness since sort will reshuffle the entries in the
// descriptor array. If the descriptor array were to be black, the shuffling
// would move a slot that was already recorded as pointing into an evacuation
@@ -7251,7 +7226,8 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
// the transition array from the map.
if (transition_index == 0 &&
!t->HasElementsTransition() &&
- !t->HasPrototypeTransitions()) {
+ !t->HasPrototypeTransitions() &&
+ t->descriptors()->IsEmpty()) {
return ClearTransitions(heap);
}
@@ -7492,8 +7468,7 @@ MaybeObject* JSFunction::SetInstancePrototype(Object* value) {
// If the function has allocated the initial map
// replace it with a copy containing the new prototype.
Map* new_map;
- MaybeObject* maybe_new_map =
- initial_map()->Copy(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_new_map = initial_map()->Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
new_map->set_prototype(value);
MaybeObject* maybe_object = set_initial_map_and_cache_transitions(new_map);
@@ -7522,7 +7497,7 @@ MaybeObject* JSFunction::SetPrototype(Object* value) {
// Remove map transitions because they point to maps with a
// different prototype.
Map* new_map;
- MaybeObject* maybe_new_map = map()->Copy(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_new_map = map()->Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
Heap* heap = new_map->GetHeap();
@@ -8816,7 +8791,7 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
Map* new_map = map->GetPrototypeTransition(value);
if (new_map == NULL) {
- MaybeObject* maybe_new_map = map->Copy(DescriptorArray::MAY_BE_SHARED);
+ MaybeObject* maybe_new_map = map->Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
MaybeObject* maybe_new_cache =
@@ -12542,8 +12517,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
// Allocate the instance descriptor.
DescriptorArray* descriptors;
MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(instance_descriptor_length,
- DescriptorArray::MAY_BE_SHARED);
+ DescriptorArray::Allocate(instance_descriptor_length);
if (!maybe_descriptors->To(&descriptors)) {
return maybe_descriptors;
}
@@ -12615,8 +12589,9 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
descriptors->Sort(witness);
+ MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors);
+ if (maybe_failure->IsFailure()) return maybe_failure;
new_map->set_unused_property_fields(unused_property_fields);
- new_map->InitializeDescriptors(descriptors);
// Transform the object.
obj->set_map(new_map);
« src/bootstrapper.cc ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698