Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c35b657

Browse files
committedApr 9, 2019
Don't treat AR hashes the same way as st hashes
We don't want to lift all AR hashes to st tables, so lets update references in AR hashes.
1 parent cb9cf46 commit c35b657

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed
 

‎gc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7537,7 +7537,7 @@ hash_foreach_replace(st_data_t key, st_data_t value, st_data_t argp, int error)
75377537
if(gc_object_moved_p(objspace, (VALUE)value)) {
75387538
return ST_REPLACE;
75397539
}
7540-
return ST_CHECK;
7540+
return ST_CONTINUE;
75417541
}
75427542

75437543
static void
@@ -7558,7 +7558,7 @@ rb_gc_update_tbl_refs(st_table *ptr)
75587558
static void
75597559
gc_ref_update_hash(rb_objspace_t * objspace, VALUE v)
75607560
{
7561-
gc_update_table_refs(objspace, rb_hash_tbl_raw(v));
7561+
rb_hash_stlike_foreach_with_replace(v, hash_foreach_replace, hash_replace_ref, (st_data_t)objspace);
75627562
}
75637563

75647564
void rb_update_st_references(struct st_table *ht)

‎hash.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash
781781
}
782782

783783
static int
784-
ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg)
784+
ar_general_foreach(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg)
785785
{
786786
if (RHASH_AR_TABLE_SIZE(hash) > 0) {
787787
unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
@@ -797,9 +797,22 @@ ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg)
797797
case ST_CONTINUE:
798798
break;
799799
case ST_CHECK:
800-
case ST_REPLACE:
801800
case ST_STOP:
802801
return 0;
802+
case ST_REPLACE:
803+
if (replace) {
804+
VALUE key;
805+
VALUE value;
806+
807+
key = cur_entry->key;
808+
value = cur_entry->record;
809+
retval = (*replace)(&key, &value, arg, TRUE);
810+
811+
ar_table_entry *entry = RHASH_AR_TABLE_REF(hash, i);
812+
entry->key = key;
813+
entry->record = value;
814+
}
815+
break;
803816
case ST_DELETE:
804817
ar_clear_entry(RHASH_AR_TABLE_REF(hash, i));
805818
RHASH_AR_TABLE_SIZE_DEC(hash);
@@ -810,6 +823,18 @@ ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg)
810823
return 0;
811824
}
812825

826+
static int
827+
ar_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg)
828+
{
829+
return ar_general_foreach(hash, func, replace, arg);
830+
}
831+
832+
static int
833+
ar_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg)
834+
{
835+
return ar_general_foreach(hash, func, NULL, arg);
836+
}
837+
813838
static int
814839
ar_foreach_check(VALUE hash, int (*func)(ANYARGS), st_data_t arg,
815840
st_data_t never)
@@ -1259,6 +1284,17 @@ rb_hash_stlike_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg)
12591284
}
12601285
}
12611286

1287+
int
1288+
rb_hash_stlike_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg)
1289+
{
1290+
if (RHASH_AR_TABLE_P(hash)) {
1291+
return ar_foreach_with_replace(hash, func, replace, arg);
1292+
}
1293+
else {
1294+
return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
1295+
}
1296+
}
1297+
12621298
static VALUE
12631299
hash_foreach_call(VALUE arg)
12641300
{

‎internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,7 @@ void rb_hash_bulk_insert(long, const VALUE *, VALUE);
15661566
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
15671567
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
15681568
int rb_hash_stlike_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg);
1569+
int rb_hash_stlike_foreach_with_replace(VALUE hash, int (*func)(ANYARGS), st_update_callback_func *replace, st_data_t arg);
15691570
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg);
15701571

15711572
/* inits.c */

0 commit comments

Comments
 (0)
Please sign in to comment.