Commit e0977e06 authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

heap: Check if ephemeron key is in construction

Visiting an ephemeron pair checks if the key is alive. It did not
check if the key was in construction. If that check happens on a
concurrent thread (that didn't happen to mark the key before) then
there is no sync between the threads (the in construction check is
generally used as the sync) and the is a data race between creating
the key and concurrently checking if it's alive.

This CL adds an in construction check for the key as a sync point.
If the ephemeron key is in construction, we treat it as marked and
trace the value (the key will be marked by the end of GC). This
allows concurrent marking to handle the value rather than leave it
for the mutator thread.
The key is marked either by the write barrier when pushing it to the
HashTable, as a previously in-construction object if we get a marking
step with no stack, or conservatively during the atomic pause (if it's
not marked by regular marking).

Bug: 1116801
Change-Id: I2b75bbca3a8986285c905eb024560c4ad2525826
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2358744Reviewed-by: default avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798735}
parent 85ccc4d8
...@@ -84,8 +84,12 @@ void MarkingVisitorBase::VisitWeak(const void* object, ...@@ -84,8 +84,12 @@ void MarkingVisitorBase::VisitWeak(const void* object,
void MarkingVisitorBase::VisitEphemeron(const void* key, void MarkingVisitorBase::VisitEphemeron(const void* key,
const void* value, const void* value,
TraceCallback value_trace_callback) { TraceCallback value_trace_callback) {
if (!HeapObjectHeader::FromPayload(key) HeapObjectHeader* key_header = HeapObjectHeader::FromPayload(key);
->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) { if (!key_header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>() &&
!key_header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
// In construction keys are considered as marked because they are
// guaranteed to be marked by the end of GC (e.g. by write barrier
// on insertion to HashTable).
discovered_ephemeron_pairs_worklist_.Push( discovered_ephemeron_pairs_worklist_.Push(
{key, value, value_trace_callback}); {key, value, value_trace_callback});
return; return;
......
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