From 5463d257cbb1879903d3a05a15851b6d154b7c47 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Thu, 21 May 2026 18:09:30 +0200 Subject: [PATCH] fix: avoid full weak sweep for CODE weaken Keep the CODE weak-ref cleanup path targeted to the CODE referent instead of running a full ReachabilityWalker sweep from WeakRefRegistry.weaken(). DBIx::Class weakens callback CODE refs in hot cursor paths, and the broad sweep was forcing repeated explicit old-GC cycles in t/87ordered.t. Generated with Codex (https://openai.com/codex) Co-Authored-By: Codex --- .../runtime/runtimetypes/WeakRefRegistry.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/perlonjava/runtime/runtimetypes/WeakRefRegistry.java b/src/main/java/org/perlonjava/runtime/runtimetypes/WeakRefRegistry.java index aa6d20f29..4fe39e063 100644 --- a/src/main/java/org/perlonjava/runtime/runtimetypes/WeakRefRegistry.java +++ b/src/main/java/org/perlonjava/runtime/runtimetypes/WeakRefRegistry.java @@ -188,17 +188,23 @@ public static void weaken(RuntimeScalar ref) { ref.refCountOwned = false; base.refCount = WEAKLY_TRACKED; } - boolean shouldSweepLiveCodeRef = weakenedLiveCodeRef + boolean shouldCheckLiveCodeRef = weakenedLiveCodeRef && codeRefHasCountedOwners(base) && !ModuleInitGuard.inModuleInit(); if (base instanceof RuntimeCode code && code.refCount >= 0 && weakRefsExist - && (shouldSweepLiveCodeRef + && (shouldCheckLiveCodeRef || (code.hadStashRef && code.stashRefCount <= 0 && !isInstalledGlobalCodeRef(code)))) { - ReachabilityWalker.sweepWeakRefs(true); + // Keep this path targeted to the CODE referent. DBIC weakens + // callback CODE refs in hot cursor paths; running a full + // ReachabilityWalker sweep here forces repeated System.gc() calls. + // The CODE-specific stale-ref decision below is enough: live CODE + // refs are protected by clearWeakRefsTo()/shouldKeepCodeWeakRefs, + // while expired anonymous or former-stash CODE refs can still clear + // their weak registry entries immediately. if (hasWeakRefsTo(code) && code.stashRefCount <= 0 && !isInstalledGlobalCodeRef(code)