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:
parent
9f37449f17
commit
840e6b6307
2 changed files with 25 additions and 10 deletions
|
@ -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
|
||||
|
|
30
id_table.c
30
id_table.c
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue