1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* id_table.c (mix_id_table_insert): do not touch list during

list->hash transition because GC can run during transition.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52421 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2015-11-01 08:17:25 +00:00
parent 9f37449f17
commit 840e6b6307
2 changed files with 25 additions and 10 deletions

View file

@ -1,3 +1,8 @@
Sun Nov 1 17:14:36 2015 Koichi Sasada <ko1@atdot.net>
* id_table.c (mix_id_table_insert): do not touch list during
list->hash transition because GC can run during transition.
Sun Nov 1 11:07:31 2015 Eric Wong <e@80x24.org>
* iseq.c (iseq_memsize): account for rb_call_cache entries

View file

@ -1427,7 +1427,8 @@ struct mix_id_table {
} aux;
};
#define LIST_P(mix) ((mix)->aux.size.capa <= ID_TABLE_USE_MIX_LIST_MAX_CAPA)
#define LIST_LIMIT_P(mix) ((mix)->aux.size.num == ID_TABLE_USE_MIX_LIST_MAX_CAPA)
#define LIST_P(mix) ((mix)->aux.size.capa <= ID_TABLE_USE_MIX_LIST_MAX_CAPA)
static struct mix_id_table *
mix_id_table_create(size_t size)
@ -1468,36 +1469,45 @@ mix_id_table_memsize(struct mix_id_table *tbl)
static int
mix_id_table_insert(struct mix_id_table *tbl, ID id, VALUE val)
{
if (LIST_P(tbl)) {
int r = list_id_table_insert(&tbl->aux.list, id, val);
int r;
if (!LIST_P(tbl)) {
if (LIST_P(tbl)) {
if (!LIST_LIMIT_P(tbl)) {
r = list_id_table_insert(&tbl->aux.list, id, val);
}
else {
/* convert to hash */
/* overflow. TODO: this promotion should be done in list_extend_table */
struct list_id_table *list = &tbl->aux.list;
struct hash_id_table *hash = &tbl->aux.hash;
struct hash_id_table hash_body;
id_key_t *keys = list->keys;
VALUE *values = TABLE_VALUES(list);
const int num = list->num;
int i;
hash_id_table_init(hash, 0);
hash_id_table_init(&hash_body, 0);
for (i=0; i<num; i++) {
hash_id_table_insert_key(hash, keys[i], values[i]);
/* note that GC can run */
hash_id_table_insert_key(&hash_body, keys[i], values[i]);
}
tbl->aux.hash = hash_body;
/* free list keys/values */
xfree(keys);
#if ID_TABLE_USE_CALC_VALUES == 0
xfree(values);
#endif
assert(LIST_P(tbl) == 0);
goto hash_insert;
}
return r;
}
else {
return hash_id_table_insert(&tbl->aux.hash, id, val);
hash_insert:
r = hash_id_table_insert(&tbl->aux.hash, id, val);
assert(!LIST_P(tbl));
}
return r;
}
static int