fix(agc): a joined host import may replace imports the build in flight already holds

A join runs before any region confirms an import and a retired import lives
through the retire-hold, so refusing it for held overlaps kept the joined run
copied for the rest of the build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlxcBTW 2026-10-13 16:51:14 +02:00 committed by Dean Galvin
parent c871b5893d
commit c29e06c693
1 changed files with 5 additions and 1 deletions

View File

@ -848,8 +848,12 @@ const HostImport* importRunAt(const Context& context, HostImports& state, Import
auto first = state.imports.lower_bound(base);
if (first != state.imports.begin() && std::prev(first)->second.base + std::prev(first)->second.bytes > base) --first;
std::uint64_t replaced = 0;
// A join may replace imports this build already looked up: it runs before any region confirms an import
// (UploadFinish's pre-pass re-resolves every pointer after it), and a retired import stays alive through the
// hold (KeepThroughHold). Refusing it there would keep the run copied for good.
const auto held = [&](const HostImport& entry) { return !joined && pointerHeld(state, entry); };
for (auto it = first; it != state.imports.end() && it->first < base + bytes; ++it) {
if (pointerHeld(state, it->second)) return nullptr;
if (held(it->second)) return nullptr;
replaced += it->second.bytes;
}
const auto budget = importBudget(context);