Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Revert "Promoting elements transitions to their own field."
Browse files Browse the repository at this point in the history
This reverts commit 09c97a6df060a7f8de6ce24457da11d6853f1a38.
  • Loading branch information
piscisaureus committed Jun 17, 2012
1 parent ae5b0e1 commit 65f6352
Show file tree
Hide file tree
Showing 21 changed files with 429 additions and 301 deletions.
2 changes: 1 addition & 1 deletion deps/v8/src/arm/macro-assembler-arm.cc
Expand Up @@ -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)));
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/ast.cc
Expand Up @@ -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...
Expand Down
6 changes: 3 additions & 3 deletions deps/v8/src/bootstrapper.cc
Expand Up @@ -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);

Expand Down Expand Up @@ -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.
Expand Down
9 changes: 3 additions & 6 deletions deps/v8/src/factory.cc
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}


Expand Down Expand Up @@ -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);
Expand Down
6 changes: 2 additions & 4 deletions deps/v8/src/heap.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/hydrogen-instructions.h
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/ia32/macro-assembler-ia32.cc
Expand Up @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/ic.cc
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 6 additions & 11 deletions deps/v8/src/mark-compact.cc
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/mips/macro-assembler-mips.cc
Expand Up @@ -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));
Expand Down
15 changes: 15 additions & 0 deletions deps/v8/src/objects-debug.cc
Expand Up @@ -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()) {
Expand Down
63 changes: 14 additions & 49 deletions deps/v8/src/objects-inl.h
Expand Up @@ -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;
}


Expand All @@ -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));
}

Expand All @@ -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.
Expand All @@ -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(
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 19 additions & 3 deletions deps/v8/src/objects-printer.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 65f6352

Please sign in to comment.