107107#elif defined RUBY_EXPORT
108108#include "internal.h"
109109#include "internal/bits.h"
110+ #include "internal/gc.h"
110111#include "internal/hash.h"
111112#include "internal/sanitizers.h"
112113#include "internal/set_table.h"
@@ -173,7 +174,14 @@ static const struct st_hash_type type_strcasehash = {
173174#define malloc ruby_xmalloc
174175#define calloc ruby_xcalloc
175176#define realloc ruby_xrealloc
177+ #define sized_realloc ruby_sized_xrealloc
176178#define free ruby_xfree
179+ #define sized_free ruby_sized_xfree
180+ #define free_fixed_ptr (v ) ruby_sized_xfree((v), sizeof(*(v)))
181+ #else
182+ #define sized_realloc (ptr , new_size , old_size ) realloc(ptr, new_size)
183+ #define sized_free (v , s ) free(v)
184+ #define free_fixed_ptr (v ) free(v)
177185#endif
178186
179187#define EQUAL (tab ,x ,y ) ((x) == (y) || (*(tab)->type->compare)((x),(y)) == 0)
@@ -551,7 +559,7 @@ st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type,
551559 tab -> bins = (st_index_t * ) malloc (bins_size (tab ));
552560#ifndef RUBY
553561 if (tab -> bins == NULL ) {
554- free (tab );
562+ free_fixed_ptr (tab );
555563 return NULL ;
556564 }
557565#endif
@@ -585,7 +593,7 @@ st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
585593 st_init_existing_table_with_size (tab , type , size );
586594#else
587595 if (st_init_existing_table_with_size (tab , type , size ) == NULL ) {
588- free (tab );
596+ free_fixed_ptr (tab );
589597 return NULL ;
590598 }
591599#endif
@@ -661,13 +669,36 @@ st_clear(st_table *tab)
661669 tab -> rebuilds_num ++ ;
662670}
663671
672+ static inline size_t
673+ st_entries_memsize (const st_table * tab )
674+ {
675+ return get_allocated_entries (tab ) * sizeof (st_table_entry );
676+ }
677+
678+ static inline size_t
679+ st_bins_memsize (const st_table * tab )
680+ {
681+ return tab -> bins == NULL ? 0 : bins_size (tab );
682+ }
683+
684+ static inline void
685+ st_free_entries (const st_table * tab )
686+ {
687+ sized_free (tab -> entries , st_entries_memsize (tab ));
688+ }
689+
690+ static inline void
691+ st_free_bins (const st_table * tab )
692+ {
693+ sized_free (tab -> bins , st_bins_memsize (tab ));
694+ }
664695/* Free table TAB space. */
665696void
666697st_free_table (st_table * tab )
667698{
668- free (tab -> bins );
669- free (tab -> entries );
670- free (tab );
699+ st_free_bins (tab );
700+ st_free_entries (tab );
701+ free_fixed_ptr (tab );
671702}
672703
673704/* Return byte size of memory allocated for table TAB. */
@@ -676,8 +707,8 @@ st_memsize(const st_table *tab)
676707{
677708 RUBY_ASSERT (tab != NULL );
678709 return (sizeof (st_table )
679- + (tab -> bins == NULL ? 0 : bins_size ( tab ) )
680- + get_allocated_entries (tab ) * sizeof ( st_table_entry ));
710+ + st_bins_memsize (tab )
711+ + st_entries_memsize (tab ));
681712}
682713
683714static st_index_t
@@ -799,14 +830,15 @@ rebuild_table_with(st_table *const new_tab, st_table *const tab)
799830static void
800831rebuild_move_table (st_table * const new_tab , st_table * const tab )
801832{
833+ st_free_bins (tab );
834+ st_free_entries (tab );
835+
802836 tab -> entry_power = new_tab -> entry_power ;
803837 tab -> bin_power = new_tab -> bin_power ;
804838 tab -> size_ind = new_tab -> size_ind ;
805- free (tab -> bins );
806839 tab -> bins = new_tab -> bins ;
807- free (tab -> entries );
808840 tab -> entries = new_tab -> entries ;
809- free (new_tab );
841+ free_fixed_ptr (new_tab );
810842}
811843
812844static void
@@ -2135,16 +2167,17 @@ st_expand_table(st_table *tab, st_index_t siz)
21352167 tmp = st_init_table_with_size (tab -> type , siz );
21362168 n = get_allocated_entries (tab );
21372169 MEMCPY (tmp -> entries , tab -> entries , st_table_entry , n );
2138- free (tab -> entries );
2139- free (tab -> bins );
2140- free (tmp -> bins );
2170+ st_free_bins (tab );
2171+ st_free_entries (tab );
2172+ st_free_bins (tmp );
2173+
21412174 tab -> entry_power = tmp -> entry_power ;
21422175 tab -> bin_power = tmp -> bin_power ;
21432176 tab -> size_ind = tmp -> size_ind ;
21442177 tab -> entries = tmp -> entries ;
21452178 tab -> bins = NULL ;
21462179 tab -> rebuilds_num ++ ;
2147- free (tmp );
2180+ free_fixed_ptr (tmp );
21482181}
21492182
21502183/* Rehash using linear search. Return TRUE if we found that the table
@@ -2156,7 +2189,7 @@ st_rehash_linear(st_table *tab)
21562189 st_index_t i , j ;
21572190 st_table_entry * p , * q ;
21582191
2159- free (tab -> bins );
2192+ st_free_bins (tab );
21602193 tab -> bins = NULL ;
21612194
21622195 for (i = tab -> entries_start ; i < tab -> entries_bound ; i ++ ) {
@@ -2188,10 +2221,11 @@ st_rehash_indexed(st_table *tab)
21882221{
21892222 int eq_p , rebuilt_p ;
21902223 st_index_t i ;
2191- st_index_t const n = bins_size (tab );
2224+
2225+ if (!tab -> bins ) {
2226+ tab -> bins = malloc (bins_size (tab ));
2227+ }
21922228 unsigned int const size_ind = get_size_ind (tab );
2193- st_index_t * bins = realloc (tab -> bins , n );
2194- tab -> bins = bins ;
21952229 initialize_bins (tab );
21962230 for (i = tab -> entries_start ; i < tab -> entries_bound ; i ++ ) {
21972231 st_table_entry * p = & tab -> entries [i ];
@@ -2207,10 +2241,10 @@ st_rehash_indexed(st_table *tab)
22072241
22082242 ind = hash_bin (p -> hash , tab );
22092243 for (;;) {
2210- st_index_t bin = get_bin (bins , size_ind , ind );
2244+ st_index_t bin = get_bin (tab -> bins , size_ind , ind );
22112245 if (EMPTY_OR_DELETED_BIN_P (bin )) {
22122246 /* ok, new room */
2213- set_bin (bins , size_ind , ind , i + ENTRY_BASE );
2247+ set_bin (tab -> bins , size_ind , ind , i + ENTRY_BASE );
22142248 break ;
22152249 }
22162250 else {
@@ -2446,6 +2480,16 @@ set_make_tab_empty(set_table *tab)
24462480 set_initialize_bins (tab );
24472481}
24482482
2483+ static inline size_t
2484+ set_entries_memsize (set_table * tab )
2485+ {
2486+ size_t memsize = set_get_allocated_entries (tab ) * sizeof (set_table_entry );
2487+ if (set_has_bins (tab )) {
2488+ memsize += set_bins_size (tab );
2489+ }
2490+ return memsize ;
2491+ }
2492+
24492493static set_table *
24502494set_init_existing_table_with_size (set_table * tab , const struct st_hash_type * type , st_index_t size )
24512495{
@@ -2471,12 +2515,7 @@ set_init_existing_table_with_size(set_table *tab, const struct st_hash_type *typ
24712515 tab -> bin_power = features [n ].bin_power ;
24722516 tab -> size_ind = features [n ].size_ind ;
24732517
2474- size_t memsize = 0 ;
2475- if (set_has_bins (tab )) {
2476- memsize += set_bins_size (tab );
2477- }
2478- memsize += set_get_allocated_entries (tab ) * sizeof (set_table_entry );
2479- tab -> entries = (set_table_entry * )malloc (memsize );
2518+ tab -> entries = (set_table_entry * )malloc (set_entries_memsize (tab ));
24802519 set_make_tab_empty (tab );
24812520 tab -> rebuilds_num = 0 ;
24822521 return tab ;
@@ -2526,8 +2565,8 @@ set_table_clear(set_table *tab)
25262565void
25272566set_free_table (set_table * tab )
25282567{
2529- free (tab -> entries );
2530- free (tab );
2568+ sized_free (tab -> entries , set_entries_memsize ( tab ) );
2569+ free_fixed_ptr (tab );
25312570}
25322571
25332572/* Return byte size of memory allocated for table TAB. */
@@ -2625,12 +2664,14 @@ set_rebuild_table_with(set_table *const new_tab, set_table *const tab)
26252664static void
26262665set_rebuild_move_table (set_table * const new_tab , set_table * const tab )
26272666{
2667+ sized_free (tab -> entries , set_entries_memsize (tab ));
2668+ tab -> entries = new_tab -> entries ;
2669+
26282670 tab -> entry_power = new_tab -> entry_power ;
26292671 tab -> bin_power = new_tab -> bin_power ;
26302672 tab -> size_ind = new_tab -> size_ind ;
2631- free (tab -> entries );
2632- tab -> entries = new_tab -> entries ;
2633- free (new_tab );
2673+
2674+ free_fixed_ptr (new_tab );
26342675}
26352676
26362677static void
0 commit comments