On 5/11/26 12:28 PM, Qian Yun wrote:
> 
> OK, maybe you are right.  The failure I saw happens in
> "insertInCache".  Maybe during "insertInCache", GC happens
> and "compactCache" is called and modifies cache array,
> causing "insertInCache" to fail.
> 
> I'll try your "allow dangling weak pointers" idea.
> 
> - Qian
> 

This should be the root cause, the timing of this kernel
cache recycle should not happen during kernel insertion.

See my attachment, this patch does not break any regression
test, and speeds up src/input/mapleok.input by 25%!

And there is room for improvement, the parameters can be
tweaked.

- Qian

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/fricas-devel/fb4fbced-335d-4b54-8f5d-5813a212a443%40gmail.com.
diff --git a/src/algebra/kl.spad b/src/algebra/kl.spad
index 0365b60f..4ec181eb 100644
--- a/src/algebra/kl.spad
+++ b/src/algebra/kl.spad
@@ -28,6 +28,8 @@ SortedCache(S : CachableSet) : Exports == Implementation where
   Exports ==> with
     clearCache  : () -> Void
       ++ clearCache() empties the cache.
+    getCache : () -> PrimitiveArray S
+    compactCache : () -> Void
     enterInCache : (S, S -> Boolean) -> S
       ++ enterInCache(x, f) enters x in the cache, calling \spad{f(y)} to
       ++ determine whether x is equal to y. It returns x with an integer
@@ -55,11 +57,21 @@ SortedCache(S : CachableSet) : Exports == Implementation where
     cache : PrimitiveArray S := empty()$(PrimitiveArray S)
     cache_size : N := 0
     cache_use : N := 0
+    getCache() == cache
+
+    compactCache() ==
+        cache_size = 0 => void()
+        ocache := cache
+        x := ocache.0
+        cache := new(cache_size, x)$(PrimitiveArray S)
+        cache_use := MAKE_WEAK_ARRAY(cache, ocache, cache_use, x)$Lisp
+        void()
 
     expandCache(x) ==
         if cache_size = cache_use then
+            compactCache()
             ocache := cache
-            cache_size := 2*cache_size + 10
+            cache_size := cache_use + 300
             cache := new(cache_size, x)$(PrimitiveArray S)
             for k in 0..(cache_use - 1) repeat
                 cache(k) := ocache(k)
@@ -67,7 +79,6 @@ SortedCache(S : CachableSet) : Exports == Implementation where
 
     insertBefore(l, x) ==
         k : Integer
-        expandCache(x)
         vscan := cache
         for k in 0..(cache_use - l - 1) repeat
             vscan(cache_use - k) := vscan(cache_use - k - 1)
@@ -95,7 +106,6 @@ SortedCache(S : CachableSet) : Exports == Implementation where
         void
 
     insertAtEnd(x : S) : Void ==
-        expandCache(x)
         cache(cache_use) := x
         cache_use := cache_use + 1
         void
@@ -166,6 +176,7 @@ SortedCache(S : CachableSet) : Exports == Implementation where
         "failed"
 
     enterInCache(x : S, triage : (S, S) -> Integer) ==
+        expandCache(x)
         zero?(cache_use) =>
             setPosition(x, DIFF)
             insertAtEnd(x)
@@ -181,6 +192,7 @@ SortedCache(S : CachableSet) : Exports == Implementation where
         insertInCache((l+1)::N, x, pos)
 
     insertInCache(before, x, pos) ==
+        expandCache(x)
         y := cache(before)
         if ((pos+1) = position y) then shiftCache(before, DIFF)
         setPosition(x, pos + (((position y) - pos)::N quo 2))
diff --git a/src/lisp/primitives.lisp b/src/lisp/primitives.lisp
index 65783b28..0f9b9a42 100644
--- a/src/lisp/primitives.lisp
+++ b/src/lisp/primitives.lisp
@@ -892,3 +892,16 @@
   `(let ((|$BreakMode| '|trapSpadErrors|))
         (declare (special |$BreakMode|))
         (CATCH '|trapSpadErrors| ,form)))
+
+(defun MAKE_WEAK_ARRAY (newarray oldarray size default_element)
+  (dotimes (i size)
+    (setf (aref newarray i) (sb-ext:make-weak-pointer (aref oldarray i)))
+    (setf (aref oldarray i) nil))
+  (sb-ext:gc :full t)
+  (do ((i 0 (1+ i)) (j 0))
+      ((= i size) j)
+    ;; In SortedCache, CachableSet will never be nil, so no multiple-value-bind here
+    (let ((val (sb-ext:weak-pointer-value (aref newarray i))))
+       (if val (progn (setf (aref newarray j) val)
+                      (setq j (1+ j))))
+       (if (> i j) (setf (aref newarray i) default_element)))))

Reply via email to