Commit d21902b2 authored by danno@chromium.org's avatar danno@chromium.org

Cache multiple ElementsKind map transition per map.

R=jkummerow@chromium.org
BUG=none
TEST=none

Review URL: http://codereview.chromium.org/8017003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9417 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 65b1ea22
......@@ -1626,13 +1626,23 @@ void MarkCompactCollector::MarkDescriptorArray(
RecordSlot(slot, slot, *slot);
if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) {
PropertyType type = details.type();
if (type < FIRST_PHANTOM_PROPERTY_TYPE) {
HeapObject* object = HeapObject::cast(value);
MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object));
if (!mark.Get()) {
SetMark(HeapObject::cast(object), mark);
marking_deque_.PushBlack(object);
}
} else if (type == ELEMENTS_TRANSITION && value->IsFixedArray()) {
// 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.
HeapObject* object = HeapObject::cast(value);
MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object));
if (!mark.Get()) {
SetMark(HeapObject::cast(object), mark);
}
}
}
// The DescriptorArray descriptors contains a pointer to its contents array,
......
......@@ -315,12 +315,25 @@ void JSObject::PrintProperties(FILE* out) {
descs->GetCallbacksObject(i)->ShortPrint(out);
PrintF(out, " (callback)\n");
break;
case ELEMENTS_TRANSITION:
case ELEMENTS_TRANSITION: {
PrintF(out, "(elements transition to ");
PrintElementsKind(out,
Map::cast(descs->GetValue(i))->elements_kind());
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;
......
This diff is collapsed.
......@@ -180,7 +180,6 @@ class PropertyDetails BASE_EMBEDDED {
PropertyDetails(PropertyAttributes attributes,
PropertyType type,
int index = 0) {
ASSERT(type != ELEMENTS_TRANSITION);
ASSERT(TypeField::is_valid(type));
ASSERT(AttributesField::is_valid(attributes));
ASSERT(StorageField::is_valid(index));
......@@ -194,23 +193,6 @@ class PropertyDetails BASE_EMBEDDED {
ASSERT(index == this->index());
}
PropertyDetails(PropertyAttributes attributes,
PropertyType type,
ElementsKind elements_kind) {
ASSERT(type == ELEMENTS_TRANSITION);
ASSERT(TypeField::is_valid(type));
ASSERT(AttributesField::is_valid(attributes));
ASSERT(StorageField::is_valid(static_cast<int>(elements_kind)));
value_ = TypeField::encode(type)
| AttributesField::encode(attributes)
| StorageField::encode(static_cast<int>(elements_kind));
ASSERT(type == this->type());
ASSERT(attributes == this->attributes());
ASSERT(elements_kind == this->elements_kind());
}
// Conversion for storing details as Object*.
explicit inline PropertyDetails(Smi* smi);
inline Smi* AsSmi();
......@@ -232,11 +214,6 @@ class PropertyDetails BASE_EMBEDDED {
int index() { return StorageField::decode(value_); }
ElementsKind elements_kind() {
ASSERT(type() == ELEMENTS_TRANSITION);
return static_cast<ElementsKind>(StorageField::decode(value_));
}
inline PropertyDetails AsDeleted();
static bool IsValidIndex(int index) {
......@@ -4176,6 +4153,8 @@ class Map: public HeapObject {
// This is undone in MarkCompactCollector::ClearNonLiveTransitions().
void CreateBackPointers();
void CreateOneBackPointer(Map* transition_target);
// Set all map transitions from this map to dead maps to null.
// Also, restore the original prototype on the targets of these
// transitions, so that we do not process this map again while
......
......@@ -115,11 +115,9 @@ class MapTransitionDescriptor: public Descriptor {
class ElementsTransitionDescriptor: public Descriptor {
public:
ElementsTransitionDescriptor(String* key,
Map* map,
ElementsKind elements_kind)
: Descriptor(key, map, PropertyDetails(NONE,
ELEMENTS_TRANSITION,
elements_kind)) { }
Object* map_or_array)
: Descriptor(key, map_or_array, PropertyDetails(NONE,
ELEMENTS_TRANSITION)) { }
};
// Marks a field name in a map so that adding the field is guaranteed
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment