зеркало из https://github.com/github/ruby.git
* eval_load.c (Init_load): delay allocating an array for rb_load_path
to avoid GC problem in very early stage. (RUBY_GC_STRESS causes GC in such stage.) * variable.c (rb_gc_mark_global_tbl): rb_global_tbl may be 0 in very early stage. * thread.c (thread_cleanup_func) [IA64]: clear register stack position. (thread_start_func_2) [IA64]: record the beginning of register stack using extra argument. (rb_gc_save_machine_context) [IA64]: record the end of register stack. * gc.c [IA64] (SET_STACK_END): record the end of register stack. (garbage_collect) [IA64]: use recorded register stack area for GC marking. (yarv_machine_stack_mark) [IA64]: GC mark from the register stack area. * yarvcore.c [IA64] (rb_gc_register_stack_start): defined. (Init_VM): store th->self on stack to fix GC problem. (Init_yarv) [IA64]: initialize the beginning of register stack. * yarvcore.h (struct rb_thread_struct) [IA64]: new members for register stack area. * thread_pthread.ci (thread_start_func_1) [IA64]: call thread_start_func_2 with the end of register stack. * cont.c (struct rb_context_struct) [IA64]: new members for register stack area. (cont_mark) [IA64]: GC mark from register stack area. (cont_free) [IA64]: free saved register stack. (cont_save_machine_stack) [IA64]: record the position and contents of the register stack. (cont_capture): store cont->self on stack to fix GC problem. (cont_restore_1) [IA64]: restore the register stack. [IA64] (register_stack_extend): new function. (cont_restore_0) [IA64]: call register_stack_extend instead of cont_restore_1. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
0dc3a071d3
Коммит
3cd5af52e9
43
ChangeLog
43
ChangeLog
|
@ -1,3 +1,46 @@
|
|||
Thu Jun 14 17:16:05 2007 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* eval_load.c (Init_load): delay allocating an array for rb_load_path
|
||||
to avoid GC problem in very early stage.
|
||||
(RUBY_GC_STRESS causes GC in such stage.)
|
||||
|
||||
* variable.c (rb_gc_mark_global_tbl): rb_global_tbl may be 0 in
|
||||
very early stage.
|
||||
|
||||
* thread.c (thread_cleanup_func) [IA64]: clear register stack position.
|
||||
(thread_start_func_2) [IA64]: record the beginning of register
|
||||
stack using extra argument.
|
||||
(rb_gc_save_machine_context) [IA64]: record the end of register
|
||||
stack.
|
||||
|
||||
* gc.c [IA64] (SET_STACK_END): record the end of register stack.
|
||||
(garbage_collect) [IA64]: use recorded register stack area for
|
||||
GC marking.
|
||||
(yarv_machine_stack_mark) [IA64]: GC mark from the register stack
|
||||
area.
|
||||
|
||||
* yarvcore.c [IA64] (rb_gc_register_stack_start): defined.
|
||||
(Init_VM): store th->self on stack to fix GC problem.
|
||||
(Init_yarv) [IA64]: initialize the beginning of register stack.
|
||||
|
||||
* yarvcore.h (struct rb_thread_struct) [IA64]: new members for
|
||||
register stack area.
|
||||
|
||||
* thread_pthread.ci (thread_start_func_1) [IA64]: call
|
||||
thread_start_func_2 with the end of register stack.
|
||||
|
||||
* cont.c (struct rb_context_struct) [IA64]: new members for register
|
||||
stack area.
|
||||
(cont_mark) [IA64]: GC mark from register stack area.
|
||||
(cont_free) [IA64]: free saved register stack.
|
||||
(cont_save_machine_stack) [IA64]: record the position and contents
|
||||
of the register stack.
|
||||
(cont_capture): store cont->self on stack to fix GC problem.
|
||||
(cont_restore_1) [IA64]: restore the register stack.
|
||||
[IA64] (register_stack_extend): new function.
|
||||
(cont_restore_0) [IA64]: call register_stack_extend instead of
|
||||
cont_restore_1.
|
||||
|
||||
Thu Jun 14 17:09:48 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser): handle more
|
||||
|
|
77
cont.c
77
cont.c
|
@ -22,6 +22,11 @@ typedef struct rb_context_struct {
|
|||
VALUE *vm_stack;
|
||||
VALUE *machine_stack;
|
||||
VALUE *machine_stack_src;
|
||||
#ifdef __ia64
|
||||
VALUE *machine_register_stack;
|
||||
VALUE *machine_register_stack_src;
|
||||
int machine_register_stack_size;
|
||||
#endif
|
||||
rb_thread_t saved_thread;
|
||||
rb_jmpbuf_t jmpbuf;
|
||||
int machine_stack_size;
|
||||
|
@ -59,6 +64,12 @@ cont_mark(void *ptr)
|
|||
rb_gc_mark_locations(cont->machine_stack,
|
||||
cont->machine_stack + cont->machine_stack_size);
|
||||
}
|
||||
#ifdef __ia64
|
||||
if (cont->machine_register_stack) {
|
||||
rb_gc_mark_locations(cont->machine_register_stack,
|
||||
cont->machine_register_stack + cont->machine_register_stack_size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
MARK_REPORT_LEAVE("cont");
|
||||
}
|
||||
|
@ -71,6 +82,9 @@ cont_free(void *ptr)
|
|||
rb_context_t *cont = ptr;
|
||||
FREE_UNLESS_NULL(cont->saved_thread.stack);
|
||||
FREE_UNLESS_NULL(cont->machine_stack);
|
||||
#ifdef __ia64
|
||||
FREE_UNLESS_NULL(cont->machine_register_stack);
|
||||
#endif
|
||||
FREE_UNLESS_NULL(cont->vm_stack);
|
||||
ruby_xfree(ptr);
|
||||
}
|
||||
|
@ -83,6 +97,10 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
|||
int size;
|
||||
|
||||
rb_gc_set_stack_end(&th->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;
|
||||
|
@ -100,6 +118,20 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
|||
}
|
||||
|
||||
MEMCPY(cont->machine_stack, cont->machine_stack_src, VALUE, size);
|
||||
|
||||
#ifdef __ia64
|
||||
rb_ia64_flushrs();
|
||||
size = cont->machine_register_stack_size = th->machine_register_stack_end - th->machine_register_stack_start;
|
||||
cont->machine_register_stack_src = th->machine_register_stack_start;
|
||||
if (cont->machine_register_stack) {
|
||||
REALLOC_N(cont->machine_register_stack, VALUE, size);
|
||||
}
|
||||
else {
|
||||
cont->machine_register_stack = ALLOC_N(VALUE, size);
|
||||
}
|
||||
|
||||
MEMCPY(cont->machine_register_stack, cont->machine_register_stack_src, VALUE, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
static rb_context_t *
|
||||
|
@ -132,9 +164,11 @@ cont_capture(volatile int *stat)
|
|||
{
|
||||
rb_context_t *cont;
|
||||
rb_thread_t *th;
|
||||
volatile VALUE contval;
|
||||
|
||||
th_stack_to_heap(GET_THREAD());
|
||||
cont = cont_new(rb_cCont);
|
||||
contval = cont->self;
|
||||
th = &cont->saved_thread;
|
||||
|
||||
cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
|
||||
|
@ -203,11 +237,50 @@ cont_restore_1(rb_context_t *cont)
|
|||
VALUE, cont->machine_stack_size);
|
||||
}
|
||||
|
||||
#ifdef __ia64
|
||||
if (cont->machine_register_stack_src) {
|
||||
MEMCPY(cont->machine_register_stack_src, cont->machine_register_stack,
|
||||
VALUE, cont->machine_register_stack_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
ruby_longjmp(cont->jmpbuf, 1);
|
||||
}
|
||||
|
||||
NORETURN(NOINLINE(static void cont_restore_0(rb_context_t *, VALUE *)));
|
||||
|
||||
#ifdef __ia64
|
||||
#define C(a) rse_##a##0, rse_##a##1, rse_##a##2, rse_##a##3, rse_##a##4
|
||||
#define E(a) rse_##a##0= rse_##a##1= rse_##a##2= rse_##a##3= rse_##a##4
|
||||
static volatile int C(a), C(b), C(c), C(d), C(e);
|
||||
static volatile int C(f), C(g), C(h), C(i), C(j);
|
||||
static volatile int C(k), C(l), C(m), C(n), C(o);
|
||||
static volatile int C(p), C(q), C(r), C(s), C(t);
|
||||
int rb_dummy_false = 0;
|
||||
NORETURN(NOINLINE(static void register_stack_extend(rb_context_t *, VALUE *)));
|
||||
static void
|
||||
register_stack_extend(rb_context_t *cont, VALUE *curr_bsp)
|
||||
{
|
||||
if (rb_dummy_false) {
|
||||
/* use registers as much as possible */
|
||||
E(a) = E(b) = E(c) = E(d) = E(e) =
|
||||
E(f) = E(g) = E(h) = E(i) = E(j) =
|
||||
E(k) = E(l) = E(m) = E(n) = E(o) =
|
||||
E(p) = E(q) = E(r) = E(s) = E(t) = 0;
|
||||
E(a) = E(b) = E(c) = E(d) = E(e) =
|
||||
E(f) = E(g) = E(h) = E(i) = E(j) =
|
||||
E(k) = E(l) = E(m) = E(n) = E(o) =
|
||||
E(p) = E(q) = E(r) = E(s) = E(t) = 0;
|
||||
}
|
||||
if (curr_bsp < cont->machine_register_stack_src+cont->machine_register_stack_size) {
|
||||
register_stack_extend(cont, (VALUE*)rb_ia64_bsp());
|
||||
}
|
||||
cont_restore_1(cont);
|
||||
}
|
||||
#undef C
|
||||
#undef E
|
||||
#endif
|
||||
|
||||
static void
|
||||
cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
|
||||
{
|
||||
|
@ -238,7 +311,11 @@ cont_restore_0(rb_context_t *cont, VALUE *addr_in_prev_frame)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef __ia64
|
||||
register_stack_extend(cont, (VALUE*)rb_ia64_bsp());
|
||||
#else
|
||||
cont_restore_1(cont);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -574,10 +574,10 @@ rb_f_autoload_p(VALUE obj, VALUE sym)
|
|||
void
|
||||
Init_load()
|
||||
{
|
||||
rb_load_path = rb_ary_new();
|
||||
rb_define_readonly_variable("$:", &rb_load_path);
|
||||
rb_define_readonly_variable("$-I", &rb_load_path);
|
||||
rb_define_readonly_variable("$LOAD_PATH", &rb_load_path);
|
||||
rb_load_path = rb_ary_new();
|
||||
|
||||
rb_define_virtual_variable("$\"", get_loaded_features, 0);
|
||||
rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
|
||||
|
|
12
gc.c
12
gc.c
|
@ -540,7 +540,12 @@ rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_F
|
|||
return (VALUE)data;
|
||||
}
|
||||
|
||||
#ifdef __ia64
|
||||
#define SET_STACK_END (rb_gc_set_stack_end(&th->machine_stack_end), th->machine_register_stack_end = rb_ia64_bsp())
|
||||
#else
|
||||
#define SET_STACK_END rb_gc_set_stack_end(&th->machine_stack_end)
|
||||
#endif
|
||||
|
||||
#define STACK_START (th->machine_stack_start)
|
||||
#define STACK_END (th->machine_stack_end)
|
||||
|
||||
|
@ -1384,10 +1389,10 @@ garbage_collect(void)
|
|||
else
|
||||
rb_gc_mark_locations(th->machine_stack_start, th->machine_stack_end + 1);
|
||||
#endif
|
||||
#ifdef __ia64__
|
||||
#ifdef __ia64
|
||||
/* mark backing store (flushed register stack) */
|
||||
/* the basic idea from guile GC code */
|
||||
rb_gc_mark_locations(rb_gc_register_stack_start, (VALUE*)rb_ia64_bsp());
|
||||
rb_gc_mark_locations(th->machine_register_stack_start, th->machine_register_stack_end);
|
||||
#endif
|
||||
#if defined(__human68k__) || defined(__mc68000__)
|
||||
rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
|
||||
|
@ -1441,6 +1446,9 @@ yarv_machine_stack_mark(rb_thread_t *th)
|
|||
rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
|
||||
}
|
||||
#endif
|
||||
#ifdef __ia64
|
||||
rb_gc_mark_locations(th->machine_register_stack_start, th->machine_register_stack_end);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
15
thread.c
15
thread.c
|
@ -276,18 +276,28 @@ thread_cleanup_func(void *th_ptr)
|
|||
rb_thread_t *th = th_ptr;
|
||||
th->status = THREAD_KILLED;
|
||||
th->machine_stack_start = th->machine_stack_end = 0;
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_start = th->machine_register_stack_end = 0;
|
||||
#endif
|
||||
native_mutex_destroy(&th->interrupt_lock);
|
||||
native_thread_destroy(th);
|
||||
}
|
||||
|
||||
static int
|
||||
thread_start_func_2(rb_thread_t *th, VALUE *stack_start)
|
||||
thread_start_func_2(rb_thread_t *th, VALUE *stack_start
|
||||
#ifdef __ia64
|
||||
, VALUE *register_stack_start
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int state;
|
||||
VALUE args = th->first_args;
|
||||
rb_proc_t *proc;
|
||||
rb_thread_t *join_th;
|
||||
th->machine_stack_start = stack_start;
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_start = register_stack_start;
|
||||
#endif
|
||||
th->thgroup = th->vm->thgroup_default;
|
||||
thread_debug("thread start: %p\n", th);
|
||||
|
||||
|
@ -1822,6 +1832,9 @@ void
|
|||
rb_gc_save_machine_context(rb_thread_t *th)
|
||||
{
|
||||
rb_gc_set_stack_end(&th->machine_stack_end);
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_end = rb_ia64_bsp();
|
||||
#endif
|
||||
setjmp(th->machine_regs);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,11 @@ Init_native_thread()
|
|||
posix_signal(SIGVTALRM, null_func);
|
||||
}
|
||||
|
||||
NOINLINE(static int thread_start_func_2(rb_thread_t *th, VALUE *stack_start));
|
||||
NOINLINE(static int thread_start_func_2(rb_thread_t *th, VALUE *stack_start
|
||||
#ifdef __ia64
|
||||
, VALUE *register_stack_start
|
||||
#endif
|
||||
));
|
||||
|
||||
static void
|
||||
native_thread_destroy(rb_thread_t *th)
|
||||
|
@ -107,7 +111,7 @@ thread_start_func_1(void *th_ptr)
|
|||
VALUE stack_start;
|
||||
|
||||
/* run */
|
||||
thread_start_func_2(th, &stack_start);
|
||||
thread_start_func_2(th, &stack_start, rb_ia64_bsp());
|
||||
}
|
||||
#if USE_THREAD_CACHE
|
||||
if (1) {
|
||||
|
|
|
@ -428,7 +428,8 @@ mark_global_entry(ID key, struct global_entry *entry)
|
|||
void
|
||||
rb_gc_mark_global_tbl(void)
|
||||
{
|
||||
st_foreach_safe(rb_global_tbl, mark_global_entry, 0);
|
||||
if (rb_global_tbl)
|
||||
st_foreach_safe(rb_global_tbl, mark_global_entry, 0);
|
||||
}
|
||||
|
||||
static ID
|
||||
|
|
11
yarvcore.c
11
yarvcore.c
|
@ -395,6 +395,9 @@ rb_thread_alloc(VALUE klass)
|
|||
|
||||
VALUE insns_name_array(void);
|
||||
extern VALUE *rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
extern VALUE *rb_gc_register_stack_start;
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
sdr(void)
|
||||
|
@ -542,12 +545,13 @@ Init_VM(void)
|
|||
{
|
||||
rb_vm_t *vm = ruby_current_vm;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE th_self;
|
||||
|
||||
/* create vm object */
|
||||
vm->self = Data_Wrap_Struct(rb_cVM, vm_mark, vm_free, vm);
|
||||
|
||||
/* create main thread */
|
||||
th->self = Data_Wrap_Struct(rb_cThread, thread_mark, thread_free, th);
|
||||
th_self = th->self = Data_Wrap_Struct(rb_cThread, thread_mark, thread_free, th);
|
||||
|
||||
vm->main_thread = th;
|
||||
vm->running_thread = th;
|
||||
|
@ -557,7 +561,7 @@ Init_VM(void)
|
|||
rb_thread_set_current(th);
|
||||
|
||||
vm->living_threads = st_init_numtable();
|
||||
st_insert(vm->living_threads, th->self, (st_data_t) th->thread_id);
|
||||
st_insert(vm->living_threads, th_self, (st_data_t) th->thread_id);
|
||||
}
|
||||
yarv_init_redefined_flag();
|
||||
}
|
||||
|
@ -575,6 +579,9 @@ Init_yarv(void)
|
|||
th_init2(th);
|
||||
th->vm = vm;
|
||||
th->machine_stack_start = rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_start = rb_gc_register_stack_start;
|
||||
#endif
|
||||
rb_thread_set_current_raw(th);
|
||||
}
|
||||
|
||||
|
|
|
@ -486,6 +486,10 @@ struct rb_thread_struct
|
|||
/* for GC */
|
||||
VALUE *machine_stack_start;
|
||||
VALUE *machine_stack_end;
|
||||
#ifdef __ia64
|
||||
VALUE *machine_register_stack_start;
|
||||
VALUE *machine_register_stack_end;
|
||||
#endif
|
||||
jmp_buf machine_regs;
|
||||
int mark_stack_len;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче