Permalink
Browse files

Revert "Promoting elements transitions to their own field."

This reverts commit 09c97a6df060a7f8de6ce24457da11d6853f1a38.
  • Loading branch information...
1 parent ae5b0e1 commit 65f63527feb02ddb4b18138da93d643725d6825c @piscisaureus piscisaureus committed Jun 17, 2012
@@ -2016,7 +2016,7 @@ void MacroAssembler::CompareMap(Register obj_map,
Map* current_map = *map;
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
- current_map = current_map->LookupElementsTransitionMap(kind);
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
if (!current_map) break;
b(eq, early_success);
cmp(obj_map, Operand(Handle<Map>(current_map)));
View
@@ -514,6 +514,7 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
// We don't know the target.
return false;
case MAP_TRANSITION:
+ case ELEMENTS_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
// Perhaps something interesting is up in the prototype chain...
@@ -1632,10 +1632,9 @@ bool Genesis::InstallNatives() {
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
MaybeObject* maybe_map =
- array_function->initial_map()->CopyDropTransitions(
- DescriptorArray::MAY_BE_SHARED);
+ array_function->initial_map()->CopyDropTransitions();
Map* new_map;
- if (!maybe_map->To(&new_map)) return false;
+ if (!maybe_map->To<Map>(&new_map)) return false;
new_map->set_elements_kind(FAST_HOLEY_ELEMENTS);
array_function->set_initial_map(new_map);
@@ -2192,6 +2191,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
break;
}
case MAP_TRANSITION:
+ case ELEMENTS_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
// Ignore non-properties.
View
@@ -115,8 +115,7 @@ Handle<ObjectHashTable> Factory::NewObjectHashTable(int at_least_space_for) {
Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) {
ASSERT(0 <= number_of_descriptors);
CALL_HEAP_FUNCTION(isolate(),
- DescriptorArray::Allocate(number_of_descriptors,
- DescriptorArray::MAY_BE_SHARED),
+ DescriptorArray::Allocate(number_of_descriptors),
DescriptorArray);
}
@@ -497,9 +496,7 @@ Handle<Map> Factory::CopyMap(Handle<Map> src,
Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) {
- CALL_HEAP_FUNCTION(isolate(),
- src->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED),
- Map);
+ CALL_HEAP_FUNCTION(isolate(), src->CopyDropTransitions(), Map);
}
@@ -942,7 +939,7 @@ Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
Handle<String> key =
SymbolFromString(Handle<String>(String::cast(entry->name())));
// Check if a descriptor with this name already exists before writing.
- if (result->LinearSearch(EXPECT_UNSORTED, *key, descriptor_count) ==
+ if (result->LinearSearch(*key, descriptor_count) ==
DescriptorArray::kNotFound) {
CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
result->Set(descriptor_count, &desc, witness);
View
@@ -3671,8 +3671,7 @@ MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) {
Map* new_map;
ASSERT(object_function->has_initial_map());
{ MaybeObject* maybe_map =
- object_function->initial_map()->CopyDropTransitions(
- DescriptorArray::MAY_BE_SHARED);
+ object_function->initial_map()->CopyDropTransitions();
if (!maybe_map->To<Map>(&new_map)) return maybe_map;
}
Object* prototype;
@@ -3820,8 +3819,7 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
fun->shared()->ForbidInlineConstructor();
} else {
DescriptorArray* descriptors;
- { MaybeObject* maybe_descriptors_obj =
- DescriptorArray::Allocate(count, DescriptorArray::MAY_BE_SHARED);
+ { MaybeObject* maybe_descriptors_obj = DescriptorArray::Allocate(count);
if (!maybe_descriptors_obj->To<DescriptorArray>(&descriptors)) {
return maybe_descriptors_obj;
}
@@ -2104,7 +2104,7 @@ class HCheckMaps: public HTemplateInstruction<2> {
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
Map* transitioned_map =
- map->LookupElementsTransitionMap(kind);
+ map->LookupElementsTransitionMap(kind, NULL);
if (transitioned_map) {
map_set->Add(Handle<Map>(transitioned_map), zone);
}
@@ -566,7 +566,7 @@ void MacroAssembler::CompareMap(Register obj,
Map* current_map = *map;
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
- current_map = current_map->LookupElementsTransitionMap(kind);
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
if (!current_map) break;
j(equal, early_success, Label::kNear);
cmp(FieldOperand(obj, HeapObject::kMapOffset),
View
@@ -1511,6 +1511,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
break;
case CONSTANT_FUNCTION:
case CONSTANT_TRANSITION:
+ case ELEMENTS_TRANSITION:
return;
case HANDLER:
case NULL_DESCRIPTOR:
@@ -1974,6 +1975,7 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
case CALLBACKS:
case INTERCEPTOR:
case CONSTANT_TRANSITION:
+ case ELEMENTS_TRANSITION:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
code = (strict_mode == kStrictMode)
@@ -1883,17 +1883,6 @@ void Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
enum_cache);
}
- // TODO(verwaest) Make sure we free unused transitions.
- if (descriptors->elements_transition_map() != NULL) {
- Object** transitions_slot = descriptors->GetTransitionsSlot();
- Object* transitions = *transitions_slot;
- base_marker()->MarkObjectAndPush(
- reinterpret_cast<HeapObject*>(transitions));
- mark_compact_collector()->RecordSlot(descriptor_start,
- transitions_slot,
- transitions);
- }
-
// If the descriptor contains a transition (value is a Map), we don't mark the
// value as live. It might be set to the NULL_DESCRIPTOR in
// ClearNonLiveTransitions later.
@@ -1932,6 +1921,12 @@ void Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
MarkAccessorPairSlot(accessors, AccessorPair::kSetterOffset);
}
break;
+ case ELEMENTS_TRANSITION:
+ // For maps with multiple elements transitions, the transition maps are
+ // stored in a FixedArray. Keep the fixed array alive but not the maps
+ // that it refers to.
+ if (value->IsFixedArray()) base_marker()->MarkObjectWithoutPush(value);
+ break;
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
@@ -3491,7 +3491,7 @@ void MacroAssembler::CompareMapAndBranch(Register obj_map,
Map* current_map = *map;
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
- current_map = current_map->LookupElementsTransitionMap(kind);
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
if (!current_map) break;
Branch(early_success, eq, obj_map, right);
right = Operand(Handle<Map>(current_map));
@@ -929,6 +929,21 @@ bool DescriptorArray::IsConsistentWithBackPointers(Map* current_map) {
return false;
}
break;
+ case ELEMENTS_TRANSITION: {
+ Object* object = GetValue(i);
+ if (!CheckOneBackPointer(current_map, object)) {
+ return false;
+ }
+ if (object->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(object);
+ for (int i = 0; i < array->length(); ++i) {
+ if (!CheckOneBackPointer(current_map, array->get(i))) {
+ return false;
+ }
+ }
+ }
+ break;
+ }
case CALLBACKS: {
Object* object = GetValue(i);
if (object->IsAccessorPair()) {
View
@@ -1876,14 +1876,9 @@ Object** FixedArray::data_start() {
bool DescriptorArray::IsEmpty() {
ASSERT(this->IsSmi() ||
- this->MayContainTransitions() ||
+ this->length() > kFirstIndex ||
this == HEAP->empty_descriptor_array());
- return this->IsSmi() || length() < kFirstIndex;
-}
-
-
-bool DescriptorArray::MayContainTransitions() {
- return length() >= kTransitionsIndex;
+ return this->IsSmi() || length() <= kFirstIndex;
}
@@ -1893,7 +1888,7 @@ int DescriptorArray::bit_field3_storage() {
}
void DescriptorArray::set_bit_field3_storage(int value) {
- ASSERT(this->MayContainTransitions());
+ ASSERT(!IsEmpty());
WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
}
@@ -1917,7 +1912,7 @@ int DescriptorArray::Search(String* name) {
// Fast case: do linear search for small arrays.
const int kMaxElementsForLinearSearch = 8;
if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
- return LinearSearch(EXPECT_SORTED, name, nof);
+ return LinearSearch(name, nof);
}
// Slow case: perform binary search.
@@ -1935,30 +1930,6 @@ int DescriptorArray::SearchWithCache(String* name) {
}
-Map* DescriptorArray::elements_transition_map() {
- if (!this->MayContainTransitions()) {
- return NULL;
- }
- Object* transition_map = get(kTransitionsIndex);
- if (transition_map == Smi::FromInt(0)) {
- return NULL;
- } else {
- return Map::cast(transition_map);
- }
-}
-
-
-void DescriptorArray::set_elements_transition_map(
- Map* transition_map, WriteBarrierMode mode) {
- ASSERT(this->length() > kTransitionsIndex);
- Heap* heap = GetHeap();
- WRITE_FIELD(this, kTransitionsOffset, transition_map);
- CONDITIONAL_WRITE_BARRIER(
- heap, this, kTransitionsOffset, transition_map, mode);
- ASSERT(DescriptorArray::cast(this));
-}
-
-
Object** DescriptorArray::GetKeySlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return HeapObject::RawField(
@@ -2044,6 +2015,7 @@ bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
switch (GetType(descriptor_number)) {
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
+ case ELEMENTS_TRANSITION:
return true;
case CALLBACKS: {
Object* value = GetValue(descriptor_number);
@@ -3499,16 +3471,6 @@ Object* Map::GetBackPointer() {
}
-Map* Map::elements_transition_map() {
- return instance_descriptors()->elements_transition_map();
-}
-
-
-void Map::set_elements_transition_map(Map* transitioned_map) {
- return instance_descriptors()->set_elements_transition_map(transitioned_map);
-}
-
-
void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
Heap* heap = GetHeap();
ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
@@ -4161,12 +4123,15 @@ MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
maps->set(kind, current_map);
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
i < kFastElementsKindCount; ++i) {
- Map* new_map;
- ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
- MaybeObject* maybe_new_map =
- current_map->CreateNextElementsTransition(next_kind);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- maps->set(next_kind, new_map);
+ ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
+ MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
+ Map* new_map = NULL;
+ if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
+ new_map->set_elements_kind(transitioned_kind);
+ maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
+ new_map);
+ if (maybe_new_map->IsFailure()) return maybe_new_map;
+ maps->set(transitioned_kind, new_map);
current_map = new_map;
}
global_context->set_js_array_maps(maps);
@@ -273,6 +273,25 @@ void JSObject::PrintProperties(FILE* out) {
descs->GetCallbacksObject(i)->ShortPrint(out);
PrintF(out, " (callback)\n");
break;
+ case ELEMENTS_TRANSITION: {
+ PrintF(out, "(elements transition to ");
+ Object* descriptor_contents = descs->GetValue(i);
+ if (descriptor_contents->IsMap()) {
+ Map* map = Map::cast(descriptor_contents);
+ PrintElementsKind(out, map->elements_kind());
+ } else {
+ FixedArray* map_array = FixedArray::cast(descriptor_contents);
+ for (int i = 0; i < map_array->length(); ++i) {
+ Map* map = Map::cast(map_array->get(i));
+ if (i != 0) {
+ PrintF(out, ", ");
+ }
+ PrintElementsKind(out, map->elements_kind());
+ }
+ }
+ PrintF(out, ")\n");
+ break;
+ }
case MAP_TRANSITION:
PrintF(out, "(map transition)\n");
break;
@@ -419,9 +438,6 @@ void JSObject::JSObjectPrint(FILE* out) {
PrintF(out,
"]\n - prototype = %p\n",
reinterpret_cast<void*>(GetPrototype()));
- PrintF(out,
- " - elements transition to = %p\n",
- reinterpret_cast<void*>(map()->elements_transition_map()));
PrintF(out, " {\n");
PrintProperties(out);
PrintElements(out);
Oops, something went wrong.

0 comments on commit 65f6352

Please sign in to comment.