Commit 2d1727f5 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

heap: Rework ephemeron trace traits and heap snapshot

This patch unifies weak and strong handling of ephemerons and adds support for
"reverse" ephemerons (strong key w/ weak value) to the heap snapshot.

It also removes dependencies on Trait::kWeakHandlingFlag in ephemeron tracing.

Bug: 1019191
Change-Id: Ic3429a6fb45663ab7fe3c59790a72384066a1892
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1897834
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: default avatarOmer Katz <omerkatz@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712628}
parent 6d423ab2
......@@ -348,18 +348,20 @@ class GC_PLUGIN_IGNORE(
key_tracing_callback_(key_tracing_callback),
value_tracing_callback_(value_tracing_callback) {}
void Process(V8EmbedderGraphBuilder* builder) {
bool Process(V8EmbedderGraphBuilder* builder) {
Traceable key = nullptr;
{
TraceKeysScope scope(builder, &key);
key_tracing_callback_(builder, const_cast<void*>(key_));
}
DCHECK(key);
DCHECK(builder->GetStateNotNull(key));
if (!builder->StateExists(key))
return false;
{
TraceValuesScope scope(builder, key);
value_tracing_callback_(builder, const_cast<void*>(value_));
}
return true;
}
private:
......@@ -378,6 +380,10 @@ class GC_PLUGIN_IGNORE(
return states_.at(traceable);
}
bool StateExists(Traceable traceable) const {
return states_.Contains(traceable);
}
State* GetStateNotNull(Traceable traceable) {
CHECK(states_.Contains(traceable));
return states_.at(traceable);
......@@ -772,6 +778,12 @@ void V8EmbedderGraphBuilder::VisitTransitiveClosure() {
// tracing can record new ephemerons, and tracing an ephemeron can add
// items to the regular worklist, we need to repeatedly process the worklist
// until a fixed point is reached.
// Because snapshots are processed in stages, there may be ephemerons that
// where key's do not have yet a state associated with them which prohibits
// them from being processed. Such ephemerons are stashed for later
// processing.
Deque<std::unique_ptr<EphemeronItem>> unprocessed_ephemerons_;
do {
// Step 1: Go through all items in the worklist using depth-first search.
while (!worklist_.empty()) {
......@@ -780,15 +792,29 @@ void V8EmbedderGraphBuilder::VisitTransitiveClosure() {
item->Process(this);
}
// Step 2: Go through ephemeron items. Only process an ephemeron item if
// its key was already observed.
// Step 2: Go through ephemeron items.
// Re-add unprocessed ephemerons from last loop iteration.
while (!unprocessed_ephemerons_.empty()) {
ephemeron_worklist_.push_back(unprocessed_ephemerons_.TakeFirst());
}
// Only process an ephemeron item if its key was already observed.
while (!ephemeron_worklist_.empty()) {
std::unique_ptr<EphemeronItem> item =
std::move(ephemeron_worklist_.front());
ephemeron_worklist_.pop_front();
item->Process(this);
if (!item->Process(this)) {
unprocessed_ephemerons_.push_back(std::move(item));
}
}
} while (!worklist_.empty());
// Re-add unprocessed ephemerons. A later invocation of VisitTransitiveClosure
// must process them.
while (!unprocessed_ephemerons_.empty()) {
ephemeron_worklist_.push_back(unprocessed_ephemerons_.TakeFirst());
}
}
} // namespace
......
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