aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c86
1 files changed, 75 insertions, 11 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 636b4972c84..7432163db25 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -359,8 +359,16 @@ static struct gcstat
359 object_ct total_floats, total_free_floats; 359 object_ct total_floats, total_free_floats;
360 object_ct total_intervals, total_free_intervals; 360 object_ct total_intervals, total_free_intervals;
361 object_ct total_buffers; 361 object_ct total_buffers;
362
363 /* Size of the ancillary arrays of live hash-table objects.
364 The objects themselves are not included (counted as vectors above). */
365 byte_ct total_hash_table_bytes;
362} gcstat; 366} gcstat;
363 367
368/* Total size of ancillary arrays of all allocated hash-table objects,
369 both dead and alive. This number is always kept up-to-date. */
370static ptrdiff_t hash_table_allocated_bytes = 0;
371
364/* Points to memory space allocated as "spare", to be freed if we run 372/* Points to memory space allocated as "spare", to be freed if we run
365 out of memory. We keep one large block, four cons-blocks, and 373 out of memory. We keep one large block, four cons-blocks, and
366 two string blocks. */ 374 two string blocks. */
@@ -3430,6 +3438,23 @@ cleanup_vector (struct Lisp_Vector *vector)
3430 } 3438 }
3431#endif 3439#endif
3432 break; 3440 break;
3441 case PVEC_HASH_TABLE:
3442 {
3443 struct Lisp_Hash_Table *h = PSEUDOVEC_STRUCT (vector, Lisp_Hash_Table);
3444 if (h->table_size > 0)
3445 {
3446 eassert (h->index_size > 1);
3447 xfree (h->index);
3448 xfree (h->key_and_value);
3449 xfree (h->next);
3450 xfree (h->hash);
3451 ptrdiff_t bytes = (h->table_size * (2 * sizeof *h->key_and_value
3452 + sizeof *h->hash
3453 + sizeof *h->next)
3454 + h->index_size * sizeof *h->index);
3455 hash_table_allocated_bytes -= bytes;
3456 }
3457 }
3433 /* Keep the switch exhaustive. */ 3458 /* Keep the switch exhaustive. */
3434 case PVEC_NORMAL_VECTOR: 3459 case PVEC_NORMAL_VECTOR:
3435 case PVEC_FREE: 3460 case PVEC_FREE:
@@ -3440,7 +3465,6 @@ cleanup_vector (struct Lisp_Vector *vector)
3440 case PVEC_WINDOW: 3465 case PVEC_WINDOW:
3441 case PVEC_BOOL_VECTOR: 3466 case PVEC_BOOL_VECTOR:
3442 case PVEC_BUFFER: 3467 case PVEC_BUFFER:
3443 case PVEC_HASH_TABLE:
3444 case PVEC_TERMINAL: 3468 case PVEC_TERMINAL:
3445 case PVEC_WINDOW_CONFIGURATION: 3469 case PVEC_WINDOW_CONFIGURATION:
3446 case PVEC_OTHER: 3470 case PVEC_OTHER:
@@ -3554,6 +3578,8 @@ sweep_vectors (void)
3554 lisp_free (lv); 3578 lisp_free (lv);
3555 } 3579 }
3556 } 3580 }
3581
3582 gcstat.total_hash_table_bytes = hash_table_allocated_bytes;
3557} 3583}
3558 3584
3559/* Maximum number of elements in a vector. This is a macro so that it 3585/* Maximum number of elements in a vector. This is a macro so that it
@@ -5606,6 +5632,28 @@ valid_lisp_object_p (Lisp_Object obj)
5606 return 0; 5632 return 0;
5607} 5633}
5608 5634
5635/* Like xmalloc, but makes allocation count toward the total consing.
5636 Return NULL for a zero-sized allocation. */
5637void *
5638hash_table_alloc_bytes (ptrdiff_t nbytes)
5639{
5640 if (nbytes == 0)
5641 return NULL;
5642 tally_consing (nbytes);
5643 hash_table_allocated_bytes += nbytes;
5644 return xmalloc (nbytes);
5645}
5646
5647/* Like xfree, but makes allocation count toward the total consing. */
5648void
5649hash_table_free_bytes (void *p, ptrdiff_t nbytes)
5650{
5651 tally_consing (-nbytes);
5652 hash_table_allocated_bytes -= nbytes;
5653 xfree (p);
5654}
5655
5656
5609/*********************************************************************** 5657/***********************************************************************
5610 Pure Storage Management 5658 Pure Storage Management
5611 ***********************************************************************/ 5659 ***********************************************************************/
@@ -5897,10 +5945,28 @@ purecopy_hash_table (struct Lisp_Hash_Table *table)
5897 pure->test.name = purecopy (table->test.name); 5945 pure->test.name = purecopy (table->test.name);
5898 pure->test.user_hash_function = purecopy (table->test.user_hash_function); 5946 pure->test.user_hash_function = purecopy (table->test.user_hash_function);
5899 pure->test.user_cmp_function = purecopy (table->test.user_cmp_function); 5947 pure->test.user_cmp_function = purecopy (table->test.user_cmp_function);
5900 pure->hash = purecopy (table->hash); 5948
5901 pure->next = purecopy (table->next); 5949 if (table->table_size > 0)
5902 pure->index = purecopy (table->index); 5950 {
5903 pure->key_and_value = purecopy (table->key_and_value); 5951 ptrdiff_t hash_bytes = table->table_size * sizeof *table->hash;
5952 pure->hash = pure_alloc (hash_bytes, -(int)sizeof *table->hash);
5953 memcpy (pure->hash, table->hash, hash_bytes);
5954
5955 ptrdiff_t next_bytes = table->table_size * sizeof *table->next;
5956 pure->next = pure_alloc (next_bytes, -(int)sizeof *table->next);
5957 memcpy (pure->next, table->next, next_bytes);
5958
5959 ptrdiff_t nvalues = table->table_size * 2;
5960 ptrdiff_t kv_bytes = nvalues * sizeof *table->key_and_value;
5961 pure->key_and_value = pure_alloc (kv_bytes,
5962 -(int)sizeof *table->key_and_value);
5963 for (ptrdiff_t i = 0; i < nvalues; i++)
5964 pure->key_and_value[i] = purecopy (table->key_and_value[i]);
5965
5966 ptrdiff_t index_bytes = table->index_size * sizeof *table->index;
5967 pure->index = pure_alloc (index_bytes, -(int)sizeof *table->index);
5968 memcpy (pure->index, table->index, index_bytes);
5969 }
5904 5970
5905 return pure; 5971 return pure;
5906} 5972}
@@ -6084,6 +6150,7 @@ total_bytes_of_live_objects (void)
6084 tot += object_bytes (gcstat.total_floats, sizeof (struct Lisp_Float)); 6150 tot += object_bytes (gcstat.total_floats, sizeof (struct Lisp_Float));
6085 tot += object_bytes (gcstat.total_intervals, sizeof (struct interval)); 6151 tot += object_bytes (gcstat.total_intervals, sizeof (struct interval));
6086 tot += object_bytes (gcstat.total_strings, sizeof (struct Lisp_String)); 6152 tot += object_bytes (gcstat.total_strings, sizeof (struct Lisp_String));
6153 tot += gcstat.total_hash_table_bytes;
6087 return tot; 6154 return tot;
6088} 6155}
6089 6156
@@ -7227,23 +7294,20 @@ process_mark_stack (ptrdiff_t base_sp)
7227 case PVEC_HASH_TABLE: 7294 case PVEC_HASH_TABLE:
7228 { 7295 {
7229 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *)ptr; 7296 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *)ptr;
7230 ptrdiff_t size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
7231 set_vector_marked (ptr); 7297 set_vector_marked (ptr);
7232 mark_stack_push_values (ptr->contents, size);
7233 mark_stack_push_value (h->test.name); 7298 mark_stack_push_value (h->test.name);
7234 mark_stack_push_value (h->test.user_hash_function); 7299 mark_stack_push_value (h->test.user_hash_function);
7235 mark_stack_push_value (h->test.user_cmp_function); 7300 mark_stack_push_value (h->test.user_cmp_function);
7236 if (h->weakness == Weak_None) 7301 if (h->weakness == Weak_None)
7237 mark_stack_push_value (h->key_and_value); 7302 mark_stack_push_values (h->key_and_value,
7303 2 * h->table_size);
7238 else 7304 else
7239 { 7305 {
7240 /* For weak tables, mark only the vector and not its 7306 /* For weak tables, don't mark the
7241 contents --- that's what makes it weak. */ 7307 contents --- that's what makes it weak. */
7242 eassert (h->next_weak == NULL); 7308 eassert (h->next_weak == NULL);
7243 h->next_weak = weak_hash_tables; 7309 h->next_weak = weak_hash_tables;
7244 weak_hash_tables = h; 7310 weak_hash_tables = h;
7245 if (!PURE_P (h->key_and_value))
7246 set_vector_marked (XVECTOR (h->key_and_value));
7247 } 7311 }
7248 break; 7312 break;
7249 } 7313 }