Browse Source

org-element: Fix leakage in objects cache

* lisp/org-element.el (org-element--cache-remove): New function.
(org-element--cache-process-request): Use new function.
(org-element-cache-reset): Do not rely on a weak hash table to handle
objects cache.

Elements used as keys in object cache cannot be garbage collected
since they appear in the :parent hierarchy in objects.  Instead we
remove entries from the objects cache whenever an element is removed
from the element cache.
Nicolas Goaziou 11 năm trước cách đây
mục cha
commit
ec65bacc14
1 tập tin đã thay đổi với 9 bổ sung4 xóa
  1. 9 4
      lisp/org-element.el

+ 9 - 4
lisp/org-element.el

@@ -4934,6 +4934,12 @@ relative to ELEMENT and store it in the objects cache."
 	((eq (org-element-type element) 'headline) nil)
 	(t (puthash element data org-element--cache-objects))))
 
+(defsubst org-element--cache-remove (element)
+  "Remove ELEMENT from cache.
+Assume ELEMENT belongs to cache and that a cache is active."
+  (avl-tree-delete org-element--cache data)
+  (remhash element org-element--cache-objects))
+
 
 ;;;; Synchronization
 
@@ -5084,7 +5090,7 @@ t otherwise."
 				   (setq up (org-element-property :parent up))
 				   (not (eq up deleted-parent))))
 			   up))
-		    (avl-tree-delete org-element--cache data))
+		    (org-element--cache-remove data))
 		   ((or (and next
 			     (not (org-element--cache-key-less-p data-key
 								 next)))
@@ -5093,7 +5099,7 @@ t otherwise."
 		    (aset request 1 pos)
 		    (aset request 4 1)
 		    (throw 'end-phase nil))
-		   (t (avl-tree-delete org-element--cache data)
+		   (t (org-element--cache-remove data)
 		      (when (= (org-element-property :end data) end)
 			(setq deleted-parent data)))))))))))
     (when (= (aref request 4) 1)
@@ -5517,8 +5523,7 @@ buffers."
       (when (org-element--cache-active-p)
 	(org-set-local 'org-element--cache
 		       (avl-tree-create #'org-element--cache-compare))
-	(org-set-local 'org-element--cache-objects
-		       (make-hash-table :weakness 'key :test #'eq))
+	(org-set-local 'org-element--cache-objects (make-hash-table :test #'eq))
 	(org-set-local 'org-element--cache-sync-keys
 		       (make-hash-table :weakness 'key :test #'eq))
 	(org-set-local 'org-element--cache-change-warning nil)