aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c146
1 files changed, 109 insertions, 37 deletions
diff --git a/src/alloc.c b/src/alloc.c
index bb8e97f8737..be98cfd5f53 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -297,20 +297,20 @@ static ptrdiff_t pure_bytes_used_non_lisp;
297 297
298static intptr_t garbage_collection_inhibited; 298static intptr_t garbage_collection_inhibited;
299 299
300/* The GC threshold in bytes, the last time it was calculated
301 from gc-cons-threshold and gc-cons-percentage. */
302static intmax_t gc_threshold;
303
300/* If nonzero, this is a warning delivered by malloc and not yet 304/* If nonzero, this is a warning delivered by malloc and not yet
301 displayed. */ 305 displayed. */
302 306
303const char *pending_malloc_warning; 307const char *pending_malloc_warning;
304 308
305#if 0 /* Normally, pointer sanity only on request... */ 309/* Pointer sanity only on request. FIXME: Code depending on
310 SUSPICIOUS_OBJECT_CHECKING is obsolete; remove it entirely. */
306#ifdef ENABLE_CHECKING 311#ifdef ENABLE_CHECKING
307#define SUSPICIOUS_OBJECT_CHECKING 1 312#define SUSPICIOUS_OBJECT_CHECKING 1
308#endif 313#endif
309#endif
310
311/* ... but unconditionally use SUSPICIOUS_OBJECT_CHECKING while the GC
312 bug is unresolved. */
313#define SUSPICIOUS_OBJECT_CHECKING 1
314 314
315#ifdef SUSPICIOUS_OBJECT_CHECKING 315#ifdef SUSPICIOUS_OBJECT_CHECKING
316struct suspicious_free_record 316struct suspicious_free_record
@@ -327,8 +327,8 @@ static int suspicious_free_history_index;
327static void *find_suspicious_object_in_range (void *begin, void *end); 327static void *find_suspicious_object_in_range (void *begin, void *end);
328static void detect_suspicious_free (void *ptr); 328static void detect_suspicious_free (void *ptr);
329#else 329#else
330# define find_suspicious_object_in_range(begin, end) NULL 330# define find_suspicious_object_in_range(begin, end) ((void *) NULL)
331# define detect_suspicious_free(ptr) (void) 331# define detect_suspicious_free(ptr) ((void) 0)
332#endif 332#endif
333 333
334/* Maximum amount of C stack to save when a GC happens. */ 334/* Maximum amount of C stack to save when a GC happens. */
@@ -4621,11 +4621,11 @@ mark_maybe_pointer (void *p)
4621 4621
4622 if (pdumper_object_p (p)) 4622 if (pdumper_object_p (p))
4623 { 4623 {
4624 enum Lisp_Type type = pdumper_find_object_type (p); 4624 int type = pdumper_find_object_type (p);
4625 if (type != PDUMPER_NO_OBJECT) 4625 if (pdumper_valid_object_type_p (type))
4626 mark_object ((type == Lisp_Symbol) 4626 mark_object (type == Lisp_Symbol
4627 ? make_lisp_symbol(p) 4627 ? make_lisp_symbol (p)
4628 : make_lisp_ptr(p, type)); 4628 : make_lisp_ptr (p, type));
4629 /* See mark_maybe_object for why we can confidently return. */ 4629 /* See mark_maybe_object for why we can confidently return. */
4630 return; 4630 return;
4631 } 4631 }
@@ -5290,9 +5290,10 @@ make_pure_float (double num)
5290 space. */ 5290 space. */
5291 5291
5292static Lisp_Object 5292static Lisp_Object
5293make_pure_bignum (struct Lisp_Bignum *value) 5293make_pure_bignum (Lisp_Object value)
5294{ 5294{
5295 size_t i, nlimbs = mpz_size (value->value); 5295 mpz_t const *n = xbignum_val (value);
5296 size_t i, nlimbs = mpz_size (*n);
5296 size_t nbytes = nlimbs * sizeof (mp_limb_t); 5297 size_t nbytes = nlimbs * sizeof (mp_limb_t);
5297 mp_limb_t *pure_limbs; 5298 mp_limb_t *pure_limbs;
5298 mp_size_t new_size; 5299 mp_size_t new_size;
@@ -5303,10 +5304,10 @@ make_pure_bignum (struct Lisp_Bignum *value)
5303 int limb_alignment = alignof (mp_limb_t); 5304 int limb_alignment = alignof (mp_limb_t);
5304 pure_limbs = pure_alloc (nbytes, - limb_alignment); 5305 pure_limbs = pure_alloc (nbytes, - limb_alignment);
5305 for (i = 0; i < nlimbs; ++i) 5306 for (i = 0; i < nlimbs; ++i)
5306 pure_limbs[i] = mpz_getlimbn (value->value, i); 5307 pure_limbs[i] = mpz_getlimbn (*n, i);
5307 5308
5308 new_size = nlimbs; 5309 new_size = nlimbs;
5309 if (mpz_sgn (value->value) < 0) 5310 if (mpz_sgn (*n) < 0)
5310 new_size = -new_size; 5311 new_size = -new_size;
5311 5312
5312 mpz_roinit_n (b->value, pure_limbs, new_size); 5313 mpz_roinit_n (b->value, pure_limbs, new_size);
@@ -5456,7 +5457,7 @@ purecopy (Lisp_Object obj)
5456 return obj; 5457 return obj;
5457 } 5458 }
5458 else if (BIGNUMP (obj)) 5459 else if (BIGNUMP (obj))
5459 obj = make_pure_bignum (XBIGNUM (obj)); 5460 obj = make_pure_bignum (obj);
5460 else 5461 else
5461 { 5462 {
5462 AUTO_STRING (fmt, "Don't know how to purify: %S"); 5463 AUTO_STRING (fmt, "Don't know how to purify: %S");
@@ -5784,6 +5785,77 @@ mark_and_sweep_weak_table_contents (void)
5784 } 5785 }
5785} 5786}
5786 5787
5788/* Return the number of bytes to cons between GCs, assuming
5789 gc-cons-threshold is THRESHOLD and gc-cons-percentage is
5790 PERCENTAGE. */
5791static intmax_t
5792consing_threshold (intmax_t threshold, Lisp_Object percentage)
5793{
5794 if (!NILP (Vmemory_full))
5795 return memory_full_cons_threshold;
5796 else
5797 {
5798 threshold = max (threshold, GC_DEFAULT_THRESHOLD / 10);
5799 if (FLOATP (percentage))
5800 {
5801 double tot = (XFLOAT_DATA (percentage)
5802 * total_bytes_of_live_objects ());
5803 if (threshold < tot)
5804 {
5805 if (tot < INTMAX_MAX)
5806 threshold = tot;
5807 else
5808 threshold = INTMAX_MAX;
5809 }
5810 }
5811 return threshold;
5812 }
5813}
5814
5815/* Adjust consing_until_gc, assuming gc-cons-threshold is THRESHOLD and
5816 gc-cons-percentage is PERCENTAGE. */
5817static Lisp_Object
5818bump_consing_until_gc (intmax_t threshold, Lisp_Object percentage)
5819{
5820 /* If consing_until_gc is negative leave it alone, since this prevents
5821 negative integer overflow and a GC would have been done soon anyway. */
5822 if (0 <= consing_until_gc)
5823 {
5824 threshold = consing_threshold (threshold, percentage);
5825 intmax_t sum;
5826 if (INT_ADD_WRAPV (consing_until_gc, threshold - gc_threshold, &sum))
5827 {
5828 /* Scale the threshold down so that consing_until_gc does
5829 not overflow. */
5830 sum = INTMAX_MAX;
5831 threshold = INTMAX_MAX - consing_until_gc + gc_threshold;
5832 }
5833 consing_until_gc = sum;
5834 gc_threshold = threshold;
5835 }
5836
5837 return Qnil;
5838}
5839
5840/* Watch changes to gc-cons-threshold. */
5841static Lisp_Object
5842watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval,
5843 Lisp_Object operation, Lisp_Object where)
5844{
5845 intmax_t threshold;
5846 if (! (INTEGERP (newval) && integer_to_intmax (newval, &threshold)))
5847 return Qnil;
5848 return bump_consing_until_gc (threshold, Vgc_cons_percentage);
5849}
5850
5851/* Watch changes to gc-cons-percentage. */
5852static Lisp_Object
5853watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval,
5854 Lisp_Object operation, Lisp_Object where)
5855{
5856 return bump_consing_until_gc (gc_cons_threshold, newval);
5857}
5858
5787/* Subroutine of Fgarbage_collect that does most of the work. */ 5859/* Subroutine of Fgarbage_collect that does most of the work. */
5788static bool 5860static bool
5789garbage_collect_1 (struct gcstat *gcst) 5861garbage_collect_1 (struct gcstat *gcst)
@@ -5926,25 +5998,8 @@ garbage_collect_1 (struct gcstat *gcst)
5926 5998
5927 unblock_input (); 5999 unblock_input ();
5928 6000
5929 if (!NILP (Vmemory_full)) 6001 consing_until_gc = gc_threshold
5930 consing_until_gc = memory_full_cons_threshold; 6002 = consing_threshold (gc_cons_threshold, Vgc_cons_percentage);
5931 else
5932 {
5933 intmax_t threshold = max (gc_cons_threshold, GC_DEFAULT_THRESHOLD / 10);
5934 if (FLOATP (Vgc_cons_percentage))
5935 {
5936 double tot = (XFLOAT_DATA (Vgc_cons_percentage)
5937 * total_bytes_of_live_objects ());
5938 if (threshold < tot)
5939 {
5940 if (tot < INTMAX_MAX)
5941 threshold = tot;
5942 else
5943 threshold = INTMAX_MAX;
5944 }
5945 }
5946 consing_until_gc = threshold;
5947 }
5948 6003
5949 if (garbage_collection_messages && NILP (Vmemory_full)) 6004 if (garbage_collection_messages && NILP (Vmemory_full))
5950 { 6005 {
@@ -7365,6 +7420,7 @@ do hash-consing of the objects allocated to pure space. */);
7365 DEFSYM (Qheap, "heap"); 7420 DEFSYM (Qheap, "heap");
7366 DEFSYM (QAutomatic_GC, "Automatic GC"); 7421 DEFSYM (QAutomatic_GC, "Automatic GC");
7367 7422
7423 DEFSYM (Qgc_cons_percentage, "gc-cons-percentage");
7368 DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); 7424 DEFSYM (Qgc_cons_threshold, "gc-cons-threshold");
7369 DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); 7425 DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots");
7370 7426
@@ -7398,6 +7454,22 @@ N should be nonnegative. */);
7398 defsubr (&Smemory_info); 7454 defsubr (&Smemory_info);
7399 defsubr (&Smemory_use_counts); 7455 defsubr (&Smemory_use_counts);
7400 defsubr (&Ssuspicious_object); 7456 defsubr (&Ssuspicious_object);
7457
7458 Lisp_Object watcher;
7459
7460 static union Aligned_Lisp_Subr Swatch_gc_cons_threshold =
7461 {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) },
7462 { .a4 = watch_gc_cons_threshold },
7463 4, 4, "watch_gc_cons_threshold", 0, 0}};
7464 XSETSUBR (watcher, &Swatch_gc_cons_threshold.s);
7465 Fadd_variable_watcher (Qgc_cons_threshold, watcher);
7466
7467 static union Aligned_Lisp_Subr Swatch_gc_cons_percentage =
7468 {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) },
7469 { .a4 = watch_gc_cons_percentage },
7470 4, 4, "watch_gc_cons_percentage", 0, 0}};
7471 XSETSUBR (watcher, &Swatch_gc_cons_percentage.s);
7472 Fadd_variable_watcher (Qgc_cons_percentage, watcher);
7401} 7473}
7402 7474
7403#ifdef HAVE_X_WINDOWS 7475#ifdef HAVE_X_WINDOWS