Fix bug in prototype transitions cache clearing introduced by r8165.

Invalid loop nesting causes full cleanup of the prototype transitions cache on every GC.

R=ager@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8634 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
vegorov@chromium.org 2011-07-13 13:16:00 +00:00
parent be1eee7063
commit 67709e5355

View File

@ -1661,31 +1661,33 @@ void MarkCompactCollector::ClearNonLiveTransitions() {
// Clear dead prototype transitions.
int number_of_transitions = map->NumberOfProtoTransitions();
FixedArray* prototype_transitions = map->unchecked_prototype_transitions();
int new_number_of_transitions = 0;
const int header = Map::kProtoTransitionHeaderSize;
const int proto_offset =
header + Map::kProtoTransitionPrototypeOffset;
const int map_offset = header + Map::kProtoTransitionMapOffset;
const int step = Map::kProtoTransitionElementsPerEntry;
for (int i = 0; i < number_of_transitions; i++) {
Object* prototype = prototype_transitions->get(proto_offset + i * step);
Object* cached_map = prototype_transitions->get(map_offset + i * step);
if (HeapObject::cast(prototype)->IsMarked() &&
HeapObject::cast(cached_map)->IsMarked()) {
if (new_number_of_transitions != i) {
prototype_transitions->set_unchecked(
heap_,
proto_offset + new_number_of_transitions * step,
prototype,
UPDATE_WRITE_BARRIER);
prototype_transitions->set_unchecked(
heap_,
map_offset + new_number_of_transitions * step,
cached_map,
SKIP_WRITE_BARRIER);
if (number_of_transitions > 0) {
FixedArray* prototype_transitions = map->unchecked_prototype_transitions();
int new_number_of_transitions = 0;
const int header = Map::kProtoTransitionHeaderSize;
const int proto_offset =
header + Map::kProtoTransitionPrototypeOffset;
const int map_offset = header + Map::kProtoTransitionMapOffset;
const int step = Map::kProtoTransitionElementsPerEntry;
for (int i = 0; i < number_of_transitions; i++) {
Object* prototype = prototype_transitions->get(proto_offset + i * step);
Object* cached_map = prototype_transitions->get(map_offset + i * step);
if (HeapObject::cast(prototype)->IsMarked() &&
HeapObject::cast(cached_map)->IsMarked()) {
if (new_number_of_transitions != i) {
prototype_transitions->set_unchecked(
heap_,
proto_offset + new_number_of_transitions * step,
prototype,
UPDATE_WRITE_BARRIER);
prototype_transitions->set_unchecked(
heap_,
map_offset + new_number_of_transitions * step,
cached_map,
SKIP_WRITE_BARRIER);
}
new_number_of_transitions++;
}
new_number_of_transitions++;
}
// Fill slots that became free with undefined value.