зеркало из https://github.com/github/ruby.git
Let execution context local storage be an ID table
This commit is contained in:
Родитель
b53d8230f1
Коммит
40c57ad4a1
|
@ -0,0 +1,8 @@
|
|||
prelude: |
|
||||
th = Thread.current
|
||||
th[:key] = :val
|
||||
benchmark:
|
||||
key?: th.key?(:key)
|
||||
[]: th[:key]
|
||||
keys: th.keys
|
||||
loop_count: 1_000_000
|
|
@ -1919,6 +1919,7 @@ cont.$(OBJEXT): {$(VPATH)}defines.h
|
|||
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
|
||||
cont.$(OBJEXT): {$(VPATH)}gc.h
|
||||
cont.$(OBJEXT): {$(VPATH)}id.h
|
||||
cont.$(OBJEXT): {$(VPATH)}id_table.h
|
||||
cont.$(OBJEXT): {$(VPATH)}intern.h
|
||||
cont.$(OBJEXT): {$(VPATH)}internal.h
|
||||
cont.$(OBJEXT): {$(VPATH)}method.h
|
||||
|
|
5
cont.c
5
cont.c
|
@ -27,6 +27,7 @@
|
|||
#include "internal/warnings.h"
|
||||
#include "mjit.h"
|
||||
#include "vm_core.h"
|
||||
#include "id_table.h"
|
||||
|
||||
static const int DEBUG = 0;
|
||||
|
||||
|
@ -1018,7 +1019,7 @@ fiber_free(void *ptr)
|
|||
//if (DEBUG) fprintf(stderr, "fiber_free: %p[%p]\n", fiber, fiber->stack.base);
|
||||
|
||||
if (fiber->cont.saved_ec.local_storage) {
|
||||
st_free_table(fiber->cont.saved_ec.local_storage);
|
||||
rb_id_table_free(fiber->cont.saved_ec.local_storage);
|
||||
}
|
||||
|
||||
cont_free(&fiber->cont);
|
||||
|
@ -1037,7 +1038,7 @@ fiber_memsize(const void *ptr)
|
|||
* vm.c::thread_memsize already counts th->ec->local_storage
|
||||
*/
|
||||
if (saved_ec->local_storage && fiber != th->root_fiber) {
|
||||
size += st_memsize(saved_ec->local_storage);
|
||||
size += rb_id_table_memsize(saved_ec->local_storage);
|
||||
}
|
||||
size += cont_memsize(&fiber->cont);
|
||||
return size;
|
||||
|
|
35
thread.c
35
thread.c
|
@ -3219,11 +3219,11 @@ threadptr_local_aref(rb_thread_t *th, ID id)
|
|||
return th->ec->local_storage_recursive_hash;
|
||||
}
|
||||
else {
|
||||
st_data_t val;
|
||||
st_table *local_storage = th->ec->local_storage;
|
||||
VALUE val;
|
||||
struct rb_id_table *local_storage = th->ec->local_storage;
|
||||
|
||||
if (local_storage != NULL && st_lookup(local_storage, id, &val)) {
|
||||
return (VALUE)val;
|
||||
if (local_storage != NULL && rb_id_table_lookup(local_storage, id, &val)) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
return Qnil;
|
||||
|
@ -3340,7 +3340,7 @@ rb_thread_fetch(int argc, VALUE *argv, VALUE self)
|
|||
return target_th->ec->local_storage_recursive_hash;
|
||||
}
|
||||
else if (id && target_th->ec->local_storage &&
|
||||
st_lookup(target_th->ec->local_storage, id, &val)) {
|
||||
rb_id_table_lookup(target_th->ec->local_storage, id, &val)) {
|
||||
return val;
|
||||
}
|
||||
else if (block_given) {
|
||||
|
@ -3362,18 +3362,18 @@ threadptr_local_aset(rb_thread_t *th, ID id, VALUE val)
|
|||
return val;
|
||||
}
|
||||
else {
|
||||
st_table *local_storage = th->ec->local_storage;
|
||||
struct rb_id_table *local_storage = th->ec->local_storage;
|
||||
|
||||
if (NIL_P(val)) {
|
||||
if (!local_storage) return Qnil;
|
||||
st_delete_wrap(local_storage, id);
|
||||
rb_id_table_delete(local_storage, id);
|
||||
return Qnil;
|
||||
}
|
||||
else {
|
||||
if (local_storage == NULL) {
|
||||
th->ec->local_storage = local_storage = st_init_numtable();
|
||||
th->ec->local_storage = local_storage = rb_id_table_create(0);
|
||||
}
|
||||
st_insert(local_storage, id, val);
|
||||
rb_id_table_insert(local_storage, id, val);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
@ -3486,13 +3486,14 @@ rb_thread_variable_set(VALUE thread, VALUE id, VALUE val)
|
|||
static VALUE
|
||||
rb_thread_key_p(VALUE self, VALUE key)
|
||||
{
|
||||
VALUE val;
|
||||
ID id = rb_check_id(&key);
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
struct rb_id_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
|
||||
if (!id || local_storage == NULL) {
|
||||
return Qfalse;
|
||||
}
|
||||
else if (st_is_member(local_storage, id)) {
|
||||
else if (rb_id_table_lookup(local_storage, id, &val)) {
|
||||
return Qtrue;
|
||||
}
|
||||
else {
|
||||
|
@ -3500,11 +3501,11 @@ rb_thread_key_p(VALUE self, VALUE key)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
thread_keys_i(ID key, VALUE value, VALUE ary)
|
||||
static enum rb_id_table_iterator_result
|
||||
thread_keys_i(ID key, VALUE value, void *ary)
|
||||
{
|
||||
rb_ary_push(ary, ID2SYM(key));
|
||||
return ST_CONTINUE;
|
||||
rb_ary_push((VALUE)ary, ID2SYM(key));
|
||||
return ID_TABLE_CONTINUE;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -3530,11 +3531,11 @@ rb_thread_alone(void)
|
|||
static VALUE
|
||||
rb_thread_keys(VALUE self)
|
||||
{
|
||||
st_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
struct rb_id_table *local_storage = rb_thread_ptr(self)->ec->local_storage;
|
||||
VALUE ary = rb_ary_new();
|
||||
|
||||
if (local_storage) {
|
||||
st_foreach(local_storage, thread_keys_i, ary);
|
||||
rb_id_table_foreach(local_storage, thread_keys_i, (void *)ary);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
|
13
vm.c
13
vm.c
|
@ -2501,6 +2501,13 @@ rb_execution_context_update(const rb_execution_context_t *ec)
|
|||
}
|
||||
}
|
||||
|
||||
static enum rb_id_table_iterator_result
|
||||
mark_local_storage_i(VALUE local, void *data)
|
||||
{
|
||||
rb_gc_mark(local);
|
||||
return ID_TABLE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
rb_execution_context_mark(const rb_execution_context_t *ec)
|
||||
{
|
||||
|
@ -2544,7 +2551,9 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
|
|||
|
||||
RUBY_MARK_UNLESS_NULL(ec->errinfo);
|
||||
RUBY_MARK_UNLESS_NULL(ec->root_svar);
|
||||
rb_mark_tbl(ec->local_storage);
|
||||
if (ec->local_storage) {
|
||||
rb_id_table_foreach_values(ec->local_storage, mark_local_storage_i, NULL);
|
||||
}
|
||||
RUBY_MARK_UNLESS_NULL(ec->local_storage_recursive_hash);
|
||||
RUBY_MARK_UNLESS_NULL(ec->local_storage_recursive_hash_for_trace);
|
||||
RUBY_MARK_UNLESS_NULL(ec->private_const_reference);
|
||||
|
@ -2639,7 +2648,7 @@ thread_memsize(const void *ptr)
|
|||
size += th->ec->vm_stack_size * sizeof(VALUE);
|
||||
}
|
||||
if (th->ec->local_storage) {
|
||||
size += st_memsize(th->ec->local_storage);
|
||||
size += rb_id_table_memsize(th->ec->local_storage);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -865,7 +865,7 @@ typedef struct rb_execution_context_struct {
|
|||
struct rb_thread_struct *thread_ptr;
|
||||
|
||||
/* storage (ec (fiber) local) */
|
||||
st_table *local_storage;
|
||||
struct rb_id_table *local_storage;
|
||||
VALUE local_storage_recursive_hash;
|
||||
VALUE local_storage_recursive_hash_for_trace;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче