aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cont.c65
-rw-r--r--gc.c38
-rw-r--r--thread.c12
-rw-r--r--thread_pthread.c32
-rw-r--r--thread_win32.c6
-rw-r--r--vm.c17
-rw-r--r--vm_core.h28
7 files changed, 100 insertions, 98 deletions
diff --git a/cont.c b/cont.c
index c89f7404f6..6b0c771efd 100644
--- a/cont.c
+++ b/cont.c
@@ -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;
-
- /* 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");
- }
+ rb_thread_t *th = GET_THREAD();
- /* save oldfib's machine stack */
+ /* save oldfib's machine stack / TODO: is it needd? */
if (!FIBER_TERMINATED_P(oldfib)) {
STACK_GROW_DIR_DETECTION;
- SET_MACHINE_STACK_END(&th->machine.stack_end);
+ SET_MACHINE_STACK_END(&th->ec.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;
+ 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->machine.stack_end - th->machine.stack_start;
- oldfib->cont.machine.stack = th->machine.stack_start;
+ 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.machine.stack_start = th->machine.stack_start;
- th->machine.stack_start = sth->machine.stack_start;
+ oldfib->cont.saved_thread.ec.machine.stack_start = th->ec.machine.stack_start;
+
/* oldfib->machine.stack_end should be NULL */
- oldfib->cont.saved_thread.machine.stack_end = 0;
+ oldfib->cont.saved_thread.ec.machine.stack_end = NULL;
+
+ /* restore thread context */
+ fiber_restore_thread(th, newfib);
+
#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);
diff --git a/gc.c b/gc.c
index 11f31693c0..7f6c1a7a79 100644
--- a/gc.c
+++ b/gc.c
@@ -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();
diff --git a/thread.c b/thread.c
index 766b3d4100..d706ee469b 100644
--- a/thread.c
+++ b/thread.c
@@ -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);
diff --git a/thread_pthread.c b/thread_pthread.c
index 242b48f15d..675a2ddbae 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -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;
diff --git a/thread_win32.c b/thread_win32.c
index 5b42310679..683fafc5ba 100644
--- a/thread_win32.c
+++ b/thread_win32.c
@@ -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);
diff --git a/vm.c b/vm.c
index 5569b87182..9054293b64 100644
--- a/vm.c
+++ b/vm.c
@@ -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);
diff --git a/vm_core.h b/vm_core.h
index a2ca6342cf..67f9641c25 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -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);