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

Unified Diff: src/objects.cc

Issue 11188031: Move DescriptorArray into the map (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: remove padding area 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 250e009b24f12c24582900bb2a4bcd89b77ab349..c9e34d587d23cdca1ed3e7fd8bb1a7861ddea4d8 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1764,23 +1764,6 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
Map* old_target = old_map->GetTransition(transition_index);
Object* result;
- // To sever a transition to a map with which the descriptors are shared, the
- // larger map (more descriptors) needs to store its own descriptors array.
- // Both sides of the severed chain need to have their own descriptors pointer
- // to store distinct descriptor arrays.
-
- // If the old_target did not yet store its own descriptors, the new
- // descriptors pointer is created for the old_target by temporarily clearing
- // the back pointer and setting its descriptor array.
-
- // This phase is executed before creating the new map since it requires
- // allocation that may fail.
- if (!old_target->StoresOwnDescriptors()) {
- DescriptorArray* old_descriptors = old_map->instance_descriptors();
- MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
- if (maybe_failure->IsFailure()) return maybe_failure;
- }
-
MaybeObject* maybe_result =
ConvertDescriptorToField(name, new_value, attributes);
if (!maybe_result->To(&result)) return maybe_result;
@@ -1801,8 +1784,7 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
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.
+ // along the entire chain of smaller maps.
Map* map;
DescriptorArray* new_descriptors = new_map->instance_descriptors();
DescriptorArray* old_descriptors = old_map->instance_descriptors();
@@ -1810,14 +1792,11 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition(
!current->IsUndefined();
current = map->GetBackPointer()) {
map = Map::cast(current);
- if (!map->HasTransitionArray()) break;
- TransitionArray* transitions = map->transitions();
- if (transitions->descriptors() != old_descriptors) break;
+ if (map->instance_descriptors() != old_descriptors) break;
map->SetEnumLength(Map::kInvalidEnumCache);
- transitions->set_descriptors(new_descriptors);
+ map->set_instance_descriptors(new_descriptors);
}
old_map->set_owns_descriptors(false);
- new_map->ClearTransitions(GetHeap());
}
old_map->SetTransition(transition_index, new_map);
@@ -2201,7 +2180,7 @@ void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
new_descriptors->CopyFrom(i, *descriptors, i, witness);
}
- Map::SetDescriptors(map, new_descriptors);
+ map->set_instance_descriptors(*new_descriptors);
}
@@ -4229,13 +4208,6 @@ 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(DescriptorFlag which,
PropertyAttributes filter) {
int result = 0;
@@ -5013,37 +4985,37 @@ MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
new_descriptors->Append(descriptor, witness);
- // 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);
- }
+ 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* 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);
- }
+ 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->instance_descriptors() != descriptors) break;
+ map->set_instance_descriptors(new_descriptors);
+ }
- transitions->set_descriptors(new_descriptors);
+ set_instance_descriptors(new_descriptors);
+ }
}
- set_transitions(transitions);
result->SetBackPointer(this);
- set_owns_descriptors(false);
-
- result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors());
+ result->InitializeDescriptors(new_descriptors);
ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
+ set_transitions(transitions);
+ set_owns_descriptors(false);
+
return result;
}
@@ -5058,13 +5030,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
MaybeObject* maybe_result = CopyDropDescriptors();
if (!maybe_result->To(&result)) return maybe_result;
- // Unless we are creating a map with no descriptors and no back pointer, we
- // insert the descriptor array locally.
- if (!descriptors->IsEmpty()) {
- MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
- if (maybe_failure->IsFailure()) return maybe_failure;
- result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
- }
+ result->InitializeDescriptors(descriptors);
if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
TransitionArray* transitions;
@@ -5075,23 +5041,6 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
- if (descriptors->IsEmpty()) {
- if (owns_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.
- ASSERT(instance_descriptors()->IsEmpty());
- set_owns_descriptors(false);
- } else {
- // If the parent did not own its own descriptors, it may share a larger
- // descriptors array already. In that case, force a split by setting
- // the descriptor array of the new map to the empty descriptor array.
- MaybeObject* maybe_failure =
- result->SetDescriptors(GetHeap()->empty_descriptor_array());
- if (maybe_failure->IsFailure()) return maybe_failure;
- }
- }
-
set_transitions(transitions);
result->SetBackPointer(this);
}
@@ -5113,7 +5062,10 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
ASSERT(kind != elements_kind());
}
- if (flag == INSERT_TRANSITION && owns_descriptors()) {
+ bool insert_transition =
+ flag == INSERT_TRANSITION && !HasElementsTransition();
+
+ if (insert_transition && owns_descriptors()) {
// In case the map owned its own descriptors, share the descriptors and
// transfer ownership to the new map.
Map* new_map;
@@ -5124,8 +5076,8 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
if (added_elements->IsFailure()) return added_elements;
new_map->set_elements_kind(kind);
+ new_map->InitializeDescriptors(instance_descriptors());
new_map->SetBackPointer(this);
- new_map->SetNumberOfOwnDescriptors(NumberOfOwnDescriptors());
set_owns_descriptors(false);
return new_map;
}
@@ -5136,24 +5088,12 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
Map* new_map;
MaybeObject* maybe_new_map = Copy();
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- ASSERT(new_map->NumberOfOwnDescriptors() == NumberOfOwnDescriptors());
+
new_map->set_elements_kind(kind);
- if (flag == INSERT_TRANSITION && !HasElementsTransition()) {
- // Map::Copy does not store the descriptor array in case it is empty, since
- // it does not insert a back pointer; implicitly indicating that its
- // descriptor array is empty. Since in this case we do want to insert a back
- // pointer, we have to manually set the empty descriptor array to force a
- // split.
- if (!new_map->StoresOwnDescriptors()) {
- ASSERT(new_map->NumberOfOwnDescriptors() == 0);
- MaybeObject* maybe_failure =
- new_map->SetDescriptors(GetHeap()->empty_descriptor_array());
- if (maybe_failure->IsFailure()) return maybe_failure;
- }
+ if (insert_transition) {
MaybeObject* added_elements = set_elements_transition_map(new_map);
if (added_elements->IsFailure()) return added_elements;
-
new_map->SetBackPointer(this);
}
@@ -7467,14 +7407,8 @@ static void TrimDescriptorArray(Heap* heap,
// Clear a possible back pointer in case the transition leads to a dead map.
// Return true in case a back pointer has been cleared and false otherwise.
-static bool ClearBackPointer(Heap* heap,
- Map* target,
- DescriptorArray* descriptors,
- bool* descriptors_owner_died) {
+static bool ClearBackPointer(Heap* heap, Map* target) {
if (Marking::MarkBitFrom(target).Get()) return false;
- if (target->instance_descriptors() == descriptors) {
- *descriptors_owner_died = true;
- }
target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
return true;
}
@@ -7494,13 +7428,18 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
int transition_index = 0;
- DescriptorArray* descriptors = t->descriptors();
+ DescriptorArray* descriptors = instance_descriptors();
bool descriptors_owner_died = false;
// Compact all live descriptors to the left.
for (int i = 0; i < t->number_of_transitions(); ++i) {
Map* target = t->GetTarget(i);
- if (!ClearBackPointer(heap, target, descriptors, &descriptors_owner_died)) {
+ if (ClearBackPointer(heap, target)) {
+ if (target->instance_descriptors() == descriptors) {
+ descriptors_owner_died = true;
+ descriptors_owner_died = true;
+ }
+ } else {
if (i != transition_index) {
String* key = t->GetKey(i);
t->SetKey(transition_index, key);
@@ -7514,10 +7453,10 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
}
if (t->HasElementsTransition() &&
- ClearBackPointer(heap,
- t->elements_transition(),
- descriptors,
- &descriptors_owner_died)) {
+ ClearBackPointer(heap, t->elements_transition())) {
+ if (t->elements_transition()->instance_descriptors() == descriptors) {
+ descriptors_owner_died = true;
+ }
t->ClearElementsTransition();
} else {
// If there are no transitions to be cleared, return.
@@ -7533,7 +7472,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
} else {
- t->set_descriptors(heap->empty_descriptor_array());
+ ASSERT(descriptors == GetHeap()->empty_descriptor_array());
}
}
@@ -13015,8 +12954,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
descriptors->Sort();
- MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors);
- if (maybe_failure->IsFailure()) return maybe_failure;
+ new_map->InitializeDescriptors(descriptors);
new_map->set_unused_property_fields(unused_property_fields);
// Transform the object.
« 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