diff options
author | Peter Zhu <peter@peterzhu.ca> | 2023-09-05 13:34:41 -0400 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2023-09-05 14:32:15 -0400 |
commit | 06a1d16dc2108c54090a0fca8b356f39ef353a99 (patch) | |
tree | a4d6321b015dd7c9afa3affe686cf4860441c9a7 /weakmap.c | |
parent | bdfa885f87b291dac8d0d390ba06b7f69f48da34 (diff) | |
download | ruby-06a1d16dc2108c54090a0fca8b356f39ef353a99.tar.gz |
Reuse allocated buffer in WeakMap
If the key exists in WeakMap and WeakKeyMap, then we can reuse the
buffer and we can avoid an allocation.
Diffstat (limited to 'weakmap.c')
-rw-r--r-- | weakmap.c | 37 |
1 files changed, 18 insertions, 19 deletions
@@ -374,17 +374,23 @@ nonspecial_obj_id(VALUE obj) } static int -wmap_aset_replace(st_data_t *key, st_data_t *val, st_data_t new_key, int existing) +wmap_aset_replace(st_data_t *key, st_data_t *val, st_data_t new_key_ptr, int existing) { + VALUE new_key = *(VALUE *)new_key_ptr; + VALUE new_val = *(((VALUE *)new_key_ptr) + 1); + if (existing) { - VALUE *orig_pair = ((VALUE *)*key); assert(orig_pair[0] == *(VALUE *)new_key); + } + else { + VALUE *pair = xmalloc(sizeof(VALUE) * 2); - wmap_free_entry(orig_pair, orig_pair + 1); + *key = (st_data_t)pair; + *val = (st_data_t)(pair + 1); } - *key = new_key; - *val = (st_data_t)(((VALUE *)new_key) + 1); + *(VALUE *)*key = new_key; + *(VALUE *)*val = new_val; return ST_CONTINUE; } @@ -396,9 +402,7 @@ wmap_aset(VALUE self, VALUE key, VALUE val) struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); - VALUE *pair = xmalloc(sizeof(VALUE) * 2); - pair[0] = key; - pair[1] = val; + VALUE pair[2] = { key, val }; st_update(w->table, (st_data_t)pair, wmap_aset_replace, (st_data_t)pair); @@ -678,7 +682,7 @@ wkmap_aref(VALUE self, VALUE key) } struct wkmap_aset_args { - VALUE *new_key; + VALUE new_key; VALUE new_val; }; @@ -687,13 +691,11 @@ wkmap_aset_replace(st_data_t *key, st_data_t *val, st_data_t data_args, int exis { struct wkmap_aset_args *args = (struct wkmap_aset_args *)data_args; - if (existing) { - VALUE *orig_key_ptr = ((VALUE *)*key); - - ruby_sized_xfree(orig_key_ptr, sizeof(VALUE)); + if (!existing) { + *key = (st_data_t)xmalloc(sizeof(VALUE)); } - *key = (st_data_t)args->new_key; + *(VALUE *)*key = args->new_key; *val = (st_data_t)args->new_val; return ST_CONTINUE; @@ -722,15 +724,12 @@ wkmap_aset(VALUE self, VALUE key, VALUE val) UNREACHABLE_RETURN(Qnil); } - VALUE *key_ptr = xmalloc(sizeof(VALUE)); - *key_ptr = key; - struct wkmap_aset_args args = { - .new_key = key_ptr, + .new_key = key, .new_val = val, }; - st_update(w->table, (st_data_t)key_ptr, wkmap_aset_replace, (st_data_t)&args); + st_update(w->table, (st_data_t)&key, wkmap_aset_replace, (st_data_t)&args); RB_OBJ_WRITTEN(self, Qundef, key); RB_OBJ_WRITTEN(self, Qundef, val); |