Commit ef0e8359 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix clearing of slots in concurrent sweeper.

This fixes an old bug uncovered by
https://chromium-review.googlesource.com/591651

The bug is a race between the concurrent sweeper clearing slots and
the mutator adding slots and trimming fixed array:

1) The sweeper starts sweeping a page with an existing fixed array.
2) The sweeper pre-caches the slots clearing mode by checking if the
   slot set pointer on the page is null or not. (This is the bug).
3) The mutator updates the fixed array such that new slots are added.
4) The mutator trims the fixed array such that the added slots are
   now in free space.
5) The sweeper adds the trimmed part of the fixed array to free list,
   but does not clear slots there because of the cached flag.
6) A new object is allocated from the free list entry and it has
   a bogus slot entry recorded.

Bug: chromium:752750
TBR: mlippautz@chromium.org
Change-Id: I4f70514fa05b692a27d992954cb4c314ef4cac07
Reviewed-on: https://chromium-review.googlesource.com/608047Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47242}
parent 3e6cf71a
......@@ -3712,9 +3712,6 @@ int MarkCompactCollector::Sweeper::RawSweep(
// Sweeper takes the marking state of the full collector.
const MarkingState state = MarkingState::Internal(p);
bool non_empty_untyped_slots = p->slot_set<OLD_TO_NEW>() != nullptr ||
p->slot_set<OLD_TO_OLD>() != nullptr;
// TODO(ulan): we don't have to clear type old-to-old slots in code space
// because the concurrent marker doesn't mark code objects. This requires
// the write barrier for code objects to check the color of the code object.
......@@ -3763,12 +3760,10 @@ int MarkCompactCollector::Sweeper::RawSweep(
p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size),
ClearRecordedSlots::kNo);
}
if (non_empty_untyped_slots) {
RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, free_end,
SlotSet::KEEP_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, free_end,
SlotSet::KEEP_EMPTY_BUCKETS);
}
RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, free_end,
SlotSet::KEEP_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, free_end,
SlotSet::KEEP_EMPTY_BUCKETS);
if (non_empty_typed_slots) {
free_ranges.insert(std::pair<uint32_t, uint32_t>(
static_cast<uint32_t>(free_start - p->address()),
......@@ -3804,12 +3799,10 @@ int MarkCompactCollector::Sweeper::RawSweep(
ClearRecordedSlots::kNo);
}
if (non_empty_untyped_slots) {
RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, p->area_end(),
SlotSet::KEEP_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, p->area_end(),
SlotSet::KEEP_EMPTY_BUCKETS);
}
RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, p->area_end(),
SlotSet::KEEP_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, p->area_end(),
SlotSet::KEEP_EMPTY_BUCKETS);
if (non_empty_typed_slots) {
free_ranges.insert(std::pair<uint32_t, uint32_t>(
static_cast<uint32_t>(free_start - p->address()),
......
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