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

move th->machine to ec->machine.

* vm_core.h: move rb_thread_t::machine to rb_execution_context_t::machine.

* vm_core.h, gc.c (rb_gc_mark_machine_stack): accept ec instead of th.
  it enables to call this func from rb_execution_context_mark() in vm.c.

* cont.c (fiber_setcontext): catch up this fix.
  fiber_restore_thread() restores machine stack information too.

* gc.c: catch up structure layout changes.

* thread.c: ditto.

* thread_pthread.c: ditto.

* thread_win32.c: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59825 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2017-09-10 15:49:45 +00:00
parent 83299c73f3
commit 4f0c9a5cc4
7 changed files with 106 additions and 104 deletions

77
cont.c
View file

@ -430,18 +430,18 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
{
size_t size;
SET_MACHINE_STACK_END(&th->machine.stack_end);
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
#ifdef __ia64
th->machine.register_stack_end = rb_ia64_bsp();
#endif
if (th->machine.stack_start > th->machine.stack_end) {
size = cont->machine.stack_size = th->machine.stack_start - th->machine.stack_end;
cont->machine.stack_src = th->machine.stack_end;
if (th->ec.machine.stack_start > th->ec.machine.stack_end) {
size = cont->machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
cont->machine.stack_src = th->ec.machine.stack_end;
}
else {
size = cont->machine.stack_size = th->machine.stack_end - th->machine.stack_start;
cont->machine.stack_src = th->machine.stack_start;
size = cont->machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
cont->machine.stack_src = th->ec.machine.stack_start;
}
if (cont->machine.stack) {
@ -485,13 +485,15 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th)
/* save thread context */
sth->ec = th->ec;
#if FIBER_USE_NATIVE
/* saved_thread->machine.stack_(start|end) should be NULL */
/* because it may happen GC afterward */
sth->machine.stack_start = 0;
sth->machine.stack_end = 0;
sth->ec.machine.stack_start = NULL;
sth->ec.machine.stack_end = NULL;
#ifdef __ia64
sth->machine.register_stack_start = 0;
sth->machine.register_stack_end = 0;
sth->ec.machine.register_stack_start = NULL;
sth->ec.machine.register_stack_end = NULL;
#endif
#endif
}
@ -501,7 +503,6 @@ cont_init(rb_context_t *cont, rb_thread_t *th)
/* save thread context */
cont_save_thread(cont, th);
cont->saved_thread.self = th->self;
cont->saved_thread.machine.stack_maxsize = th->machine.stack_maxsize;
cont->saved_thread.ec.local_storage = NULL;
cont->saved_thread.ec.local_storage_recursive_hash = Qnil;
@ -651,7 +652,7 @@ fiber_set_stack_location(void)
VALUE *ptr;
SET_MACHINE_STACK_END(&ptr);
th->machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE));
th->ec.machine.stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE));
}
static VOID CALLBACK
@ -730,7 +731,7 @@ fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size)
rb_raise(rb_eFiberError, "can't create fiber");
}
}
sth->machine.stack_maxsize = size;
sth->ec.machine.stack_maxsize = size;
#else /* not WIN32 */
ucontext_t *context = &fib->context;
char *ptr;
@ -744,8 +745,8 @@ fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size)
fib->ss_sp = ptr;
fib->ss_size = size;
makecontext(context, rb_fiber_start, 0);
sth->machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size));
sth->machine.stack_maxsize = size - RB_PAGE_SIZE;
sth->ec.machine.stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size));
sth->ec.machine.stack_maxsize = size - RB_PAGE_SIZE;
#endif
#ifdef __ia64
sth->machine.register_stack_maxsize = sth->machine.stack_maxsize;
@ -757,33 +758,31 @@ NOINLINE(static void fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib));
static void
fiber_setcontext(rb_fiber_t *newfib, rb_fiber_t *oldfib)
{
rb_thread_t *th = GET_THREAD(), *sth = &newfib->cont.saved_thread;
rb_thread_t *th = GET_THREAD();
/* save oldfib's machine stack / TODO: is it needd? */
if (!FIBER_TERMINATED_P(oldfib)) {
STACK_GROW_DIR_DETECTION;
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
if (STACK_DIR_UPPER(0, 1)) {
oldfib->cont.machine.stack_size = th->ec.machine.stack_start - th->ec.machine.stack_end;
oldfib->cont.machine.stack = th->ec.machine.stack_end;
}
else {
oldfib->cont.machine.stack_size = th->ec.machine.stack_end - th->ec.machine.stack_start;
oldfib->cont.machine.stack = th->ec.machine.stack_start;
}
}
/* exchange machine_stack_start between oldfib and newfib */
oldfib->cont.saved_thread.ec.machine.stack_start = th->ec.machine.stack_start;
/* oldfib->machine.stack_end should be NULL */
oldfib->cont.saved_thread.ec.machine.stack_end = NULL;
/* restore thread context */
fiber_restore_thread(th, newfib);
th->machine.stack_maxsize = sth->machine.stack_maxsize;
if (sth->machine.stack_end && (newfib != oldfib)) {
rb_bug("fiber_setcontext: sth->machine.stack_end has non zero value");
}
/* save oldfib's machine stack */
if (!FIBER_TERMINATED_P(oldfib)) {
STACK_GROW_DIR_DETECTION;
SET_MACHINE_STACK_END(&th->machine.stack_end);
if (STACK_DIR_UPPER(0, 1)) {
oldfib->cont.machine.stack_size = th->machine.stack_start - th->machine.stack_end;
oldfib->cont.machine.stack = th->machine.stack_end;
}
else {
oldfib->cont.machine.stack_size = th->machine.stack_end - th->machine.stack_start;
oldfib->cont.machine.stack = th->machine.stack_start;
}
}
/* exchange machine_stack_start between oldfib and newfib */
oldfib->cont.saved_thread.machine.stack_start = th->machine.stack_start;
th->machine.stack_start = sth->machine.stack_start;
/* oldfib->machine.stack_end should be NULL */
oldfib->cont.saved_thread.machine.stack_end = 0;
#ifndef _WIN32
if (!newfib->context.uc_stack.ss_sp && th->root_fiber != newfib) {
rb_bug("non_root_fiber->context.uc_stac.ss_sp should not be NULL");
@ -1791,7 +1790,7 @@ Init_Cont(void)
#else /* not WIN32 */
pagesize = sysconf(_SC_PAGESIZE);
#endif
SET_MACHINE_STACK_END(&th->machine.stack_end);
SET_MACHINE_STACK_END(&th->ec.machine.stack_end);
#endif
rb_cFiber = rb_define_class("Fiber", rb_cObject);

38
gc.c
View file

@ -3967,14 +3967,14 @@ init_mark_stack(mark_stack_t *stack)
/* Marking */
#ifdef __ia64
#define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine.stack_end), th->machine.register_stack_end = rb_ia64_bsp())
#define SET_STACK_END (SET_MACHINE_STACK_END(&ec->machine.stack_end), ec->machine.register_stack_end = rb_ia64_bsp())
#else
#define SET_STACK_END SET_MACHINE_STACK_END(&th->machine.stack_end)
#define SET_STACK_END SET_MACHINE_STACK_END(&ec->machine.stack_end)
#endif
#define STACK_START (th->machine.stack_start)
#define STACK_END (th->machine.stack_end)
#define STACK_LEVEL_MAX (th->machine.stack_maxsize/sizeof(VALUE))
#define STACK_START (ec->machine.stack_start)
#define STACK_END (ec->machine.stack_end)
#define STACK_LEVEL_MAX (ec->machine.stack_maxsize/sizeof(VALUE))
#if STACK_GROW_DIRECTION < 0
# define STACK_LENGTH (size_t)(STACK_START - STACK_END)
@ -4000,7 +4000,7 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
size_t
ruby_stack_length(VALUE **p)
{
rb_thread_t *th = GET_THREAD();
rb_execution_context_t *ec = &GET_THREAD()->ec;
SET_STACK_END;
if (p) *p = STACK_UPPER(STACK_END, STACK_START, STACK_END);
return STACK_LENGTH;
@ -4018,13 +4018,14 @@ ruby_stack_length(VALUE **p)
static int
stack_check(rb_thread_t *th, int water_mark)
{
rb_execution_context_t *ec = &th->ec;
int ret;
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE*)rb_ia64_bsp() - th->machine.register_stack_start >
th->machine.register_stack_maxsize/sizeof(VALUE) - water_mark;
ret = (VALUE*)rb_ia64_bsp() - ec->machine.register_stack_start >
ec->machine.register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
@ -4235,11 +4236,11 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
((start) = STACK_END, (end) = STACK_START) : ((start) = STACK_START, (end) = STACK_END+(appendix)))
#endif
static void mark_stack_locations(rb_objspace_t *objspace, rb_thread_t *th,
static void mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end);
static void
mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th)
mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec)
{
union {
rb_jmp_buf j;
@ -4259,29 +4260,29 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th)
mark_locations_array(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v));
mark_stack_locations(objspace, th, stack_start, stack_end);
mark_stack_locations(objspace, ec, stack_start, stack_end);
}
void
rb_gc_mark_machine_stack(rb_thread_t *th)
rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
{
rb_objspace_t *objspace = rb_objspace_of(th->vm);
rb_objspace_t *objspace = &rb_objspace;
VALUE *stack_start, *stack_end;
GET_STACK_BOUNDS(stack_start, stack_end, 0);
mark_stack_locations(objspace, th, stack_start, stack_end);
mark_stack_locations(objspace, ec, stack_start, stack_end);
}
static void
mark_stack_locations(rb_objspace_t *objspace, rb_thread_t *th,
mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
const VALUE *stack_start, const VALUE *stack_end)
{
gc_mark_locations(objspace, stack_start, stack_end);
#ifdef __ia64
gc_mark_locations(objspace,
th->machine.register_stack_start,
th->machine.register_stack_end);
ec->machine.register_stack_start,
ec->machine.register_stack_end);
#endif
#if defined(__mc68000__)
gc_mark_locations(objspace,
@ -4774,6 +4775,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
{
struct gc_list *list;
rb_thread_t *th = GET_THREAD();
rb_execution_context_t *ec = &th->ec;
#if PRINT_ROOT_TICKS
tick_t start_tick = tick();
@ -4820,7 +4822,7 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
mark_tbl(objspace, finalizer_table);
MARK_CHECKPOINT("machine_context");
mark_current_machine_context(objspace, th);
mark_current_machine_context(objspace, &th->ec);
MARK_CHECKPOINT("encodings");
rb_gc_mark_encodings();

View file

@ -138,8 +138,8 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio
do { \
FLUSH_REGISTER_WINDOWS; \
RB_GC_SAVE_MACHINE_REGISTER_STACK(th); \
setjmp((th)->machine.regs); \
SET_MACHINE_STACK_END(&(th)->machine.stack_end); \
setjmp((th)->ec.machine.regs); \
SET_MACHINE_STACK_END(&(th)->ec.machine.stack_end); \
} while (0)
#define GVL_UNLOCK_BEGIN() do { \
@ -525,9 +525,9 @@ thread_cleanup_func_before_exec(void *th_ptr)
{
rb_thread_t *th = th_ptr;
th->status = THREAD_KILLED;
th->machine.stack_start = th->machine.stack_end = 0;
th->ec.machine.stack_start = th->ec.machine.stack_end = NULL;
#ifdef __ia64
th->machine.register_stack_start = th->machine.register_stack_end = 0;
th->ec.machine.register_stack_start = th->ec.machine.register_stack_end = NULL;
#endif
}
@ -613,9 +613,9 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
ruby_thread_set_native(th);
th->machine.stack_start = stack_start;
th->ec.machine.stack_start = stack_start;
#ifdef __ia64
th->machine.register_stack_start = register_stack_start;
th->ec.machine.register_stack_start = register_stack_start;
#endif
thread_debug("thread start: %p\n", (void *)th);

View file

@ -832,8 +832,8 @@ native_thread_init_stack(rb_thread_t *th)
rb_nativethread_id_t curr = pthread_self();
if (pthread_equal(curr, native_main_thread.id)) {
th->machine.stack_start = native_main_thread.stack_start;
th->machine.stack_maxsize = native_main_thread.stack_maxsize;
th->ec.machine.stack_start = native_main_thread.stack_start;
th->ec.machine.stack_maxsize = native_main_thread.stack_maxsize;
}
else {
#ifdef STACKADDR_AVAILABLE
@ -841,11 +841,11 @@ native_thread_init_stack(rb_thread_t *th)
size_t size;
if (get_stack(&start, &size) == 0) {
th->machine.stack_start = start;
th->machine.stack_maxsize = size;
th->ec.machine.stack_start = start;
th->ec.machine.stack_maxsize = size;
}
#elif defined get_stack_of
if (!th->machine.stack_maxsize) {
if (!th->ec.machine.stack_maxsize) {
native_mutex_lock(&th->interrupt_lock);
native_mutex_unlock(&th->interrupt_lock);
}
@ -854,9 +854,9 @@ native_thread_init_stack(rb_thread_t *th)
#endif
}
#ifdef __ia64
th->machine.register_stack_start = native_main_thread.register_stack_start;
th->machine.stack_maxsize /= 2;
th->machine.register_stack_maxsize = th->machine.stack_maxsize;
th->ec.machine.register_stack_start = native_main_thread.register_stack_start;
th->ec.machine.stack_maxsize /= 2;
th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize;
#endif
return 0;
}
@ -884,7 +884,7 @@ thread_start_func_1(void *th_ptr)
native_thread_init(th);
/* run */
#if defined USE_NATIVE_THREAD_INIT
thread_start_func_2(th, th->machine.stack_start, rb_ia64_bsp());
thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp());
#else
thread_start_func_2(th, &stack_start, rb_ia64_bsp());
#endif
@ -1006,10 +1006,10 @@ native_thread_create(rb_thread_t *th)
const size_t stack_size = th->vm->default_params.thread_machine_stack_size;
const size_t space = space_size(stack_size);
th->machine.stack_maxsize = stack_size - space;
th->ec.machine.stack_maxsize = stack_size - space;
#ifdef __ia64
th->machine.stack_maxsize /= 2;
th->machine.register_stack_maxsize = th->machine.stack_maxsize;
th->ec.machine.stack_maxsize /= 2;
th->ec.machine.register_stack_maxsize = th->ec.machine.stack_maxsize;
#endif
#ifdef HAVE_PTHREAD_ATTR_INIT
@ -1032,8 +1032,8 @@ native_thread_create(rb_thread_t *th)
#ifdef get_stack_of
if (!err) {
get_stack_of(th->thread_id,
&th->machine.stack_start,
&th->machine.stack_maxsize);
&th->ec.machine.stack_start,
&th->ec.machine.stack_maxsize);
}
native_mutex_unlock(&th->interrupt_lock);
#endif
@ -1745,8 +1745,8 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr)
else
#endif
if (th) {
size = th->machine.stack_maxsize;
base = (char *)th->machine.stack_start - STACK_DIR_UPPER(0, size);
size = th->ec.machine.stack_maxsize;
base = (char *)th->ec.machine.stack_start - STACK_DIR_UPPER(0, size);
}
else {
return 0;

View file

@ -546,8 +546,8 @@ native_thread_init_stack(rb_thread_t *th)
size = end - base;
space = size / 5;
if (space > 1024*1024) space = 1024*1024;
th->machine.stack_start = (VALUE *)end - 1;
th->machine.stack_maxsize = size - space;
th->ec.machine.stack_start = (VALUE *)end - 1;
th->ec.machine.stack_maxsize = size - space;
}
#ifndef InterlockedExchangePointer
@ -575,7 +575,7 @@ thread_start_func_1(void *th_ptr)
thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
th->thread_id, th->native_thread_data.interrupt_event);
thread_start_func_2(th, th->machine.stack_start, rb_ia64_bsp());
thread_start_func_2(th, th->ec.machine.stack_start, rb_ia64_bsp());
w32_close_handle(thread_id);
thread_debug("thread deleted (th: %p)\n", th);

17
vm.c
View file

@ -2390,6 +2390,15 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
}
}
/* mark machine stack */
if (&GET_THREAD()->ec != ec &&
ec->machine.stack_start && ec->machine.stack_end) {
rb_gc_mark_machine_stack(ec);
rb_gc_mark_locations((VALUE *)&ec->machine.regs,
(VALUE *)(&ec->machine.regs) +
sizeof(ec->machine.regs) / sizeof(VALUE));
}
RUBY_MARK_UNLESS_NULL(ec->errinfo);
RUBY_MARK_UNLESS_NULL(ec->root_svar);
rb_mark_tbl(ec->local_storage);
@ -2406,14 +2415,6 @@ rb_thread_mark(void *ptr)
rb_execution_context_mark(&th->ec);
/* mark machine stack */
if (GET_THREAD() != th && th->machine.stack_start && th->machine.stack_end) {
rb_gc_mark_machine_stack(th);
rb_gc_mark_locations((VALUE *)&th->machine.regs,
(VALUE *)(&th->machine.regs) +
sizeof(th->machine.regs) / sizeof(VALUE));
}
/* mark ruby objects */
RUBY_MARK_UNLESS_NULL(th->first_proc);
if (th->first_proc) RUBY_MARK_UNLESS_NULL(th->first_args);

View file

@ -767,6 +767,19 @@ typedef struct rb_execution_context_struct {
rb_ensure_list_t *ensure_list;
rb_fiber_t *fiber;
/* for GC */
struct {
VALUE *stack_start;
VALUE *stack_end;
size_t stack_maxsize;
#ifdef __ia64
VALUE *register_stack_start;
VALUE *register_stack_end;
size_t register_stack_maxsize;
#endif
jmp_buf regs;
} machine;
} rb_execution_context_t;
typedef struct rb_thread_struct {
@ -829,19 +842,6 @@ typedef struct rb_thread_struct {
VALUE first_args;
VALUE (*first_func)(ANYARGS);
/* for GC */
struct {
VALUE *stack_start;
VALUE *stack_end;
size_t stack_maxsize;
#ifdef __ia64
VALUE *register_stack_start;
VALUE *register_stack_end;
size_t register_stack_maxsize;
#endif
jmp_buf regs;
} machine;
/* statistics data for profiler */
VALUE stat_insn_usage;
@ -1543,7 +1543,7 @@ void rb_vm_register_special_exception_str(enum ruby_special_exceptions sp, VALUE
#define rb_vm_register_special_exception(sp, e, m) \
rb_vm_register_special_exception_str(sp, e, rb_usascii_str_new_static((m), (long)rb_strlen_lit(m)))
void rb_gc_mark_machine_stack(rb_thread_t *th);
void rb_gc_mark_machine_stack(const rb_execution_context_t *ec);
int rb_autoloading_value(VALUE mod, ID id, VALUE* value);