Handle map transitions in CALLBACKS when doing map tree traversal.

We will have such transitions in the future and this CL is necessary to keep
slack tracking working then.

Review URL: https://chromiumcodereview.appspot.com/9285008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10494 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2012-01-25 07:26:07 +00:00
parent 12f982cf6a
commit 891f0efa3f

View File

@ -4954,15 +4954,43 @@ class IntrusiveMapTransitionIterator {
Map* Next() {
ASSERT(IsIterating());
FixedArray* contents = ContentArray();
// Attention, tricky index manipulation ahead: Every entry in the contents
// array consists of a value/details pair, so the index is typically even.
// An exception is made for CALLBACKS entries: An even index means we look
// at its getter, and an odd index means we look at its setter.
int index = Smi::cast(*ContentHeader())->value();
while (index < contents->length()) {
int next_index = index + 2;
PropertyDetails details(Smi::cast(contents->get(index + 1)));
if (details.IsTransition()) {
*ContentHeader() = Smi::FromInt(next_index);
return static_cast<Map*>(contents->get(index));
PropertyDetails details(Smi::cast(contents->get(index | 1)));
switch (details.type()) {
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
case ELEMENTS_TRANSITION:
// We definitely have a map transition.
*ContentHeader() = Smi::FromInt(index + 2);
return static_cast<Map*>(contents->get(index));
case CALLBACKS: {
// We might have a map transition in a getter or in a setter.
AccessorPair* accessors =
static_cast<AccessorPair*>(contents->get(index & ~1));
Object* accessor =
((index & 1) == 0) ? accessors->getter() : accessors->setter();
index++;
if (accessor->IsMap()) {
*ContentHeader() = Smi::FromInt(index);
return static_cast<Map*>(accessor);
}
break;
}
case NORMAL:
case FIELD:
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
case NULL_DESCRIPTOR:
// We definitely have no map transition.
index += 2;
break;
}
index = next_index;
}
*ContentHeader() = descriptor_array_->GetHeap()->fixed_array_map();
return NULL;