Project

General

Profile

Feature #2294 ยป ruby_bind_stack.patch

update API docs - remove confusing note about stack top & bottom - sunaku (Suraj Kurapati), 10/30/2009 03:55 PM

View differences:

ChangeLog
165 165

  
166 166
	* io.c (io_cntl): F_DUPFD is platform dependent.
167 167

  
168
Mon Oct 25 13:28:00 2009  Suraj N. Kurapati <sunaku@gmail.com>
169

  
170
	* include/ruby/ruby.h: declare ruby_bind_stack(). [ruby-core:26361]
171

  
172
	* gc.c: implement ruby_bind_stack().  restrict GC marking
173
	  region to ruby_bind_stack() boundaries for main thread.
174
	  refactor common code from mark_current_machine_context()
175
	  and rb_gc_mark_machine_stack() into get_machine_stack_bounds().
176

  
168 177
Sun Oct 25 10:19:09 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>
169 178

  
170 179
	* ext/dl/handle.c (rb_dlhandle_close): fixed an invalid local
gc.c
19 19
#include "eval_intern.h"
20 20
#include "vm_core.h"
21 21
#include "gc.h"
22
#include <assert.h>
22 23
#include <stdio.h>
23 24
#include <setjmp.h>
24 25
#include <sys/types.h>
......
2089 2090

  
2090 2091
void rb_vm_mark(void *ptr);
2091 2092

  
2093
static VALUE *ruby_stack_lower_bound = 0,
2094
             *ruby_stack_upper_bound = 0;
2095

  
2096
void
2097
ruby_bind_stack(void *lower, void *upper)
2098
{
2099
    assert(upper > lower);
2100
    ruby_stack_lower_bound = lower;
2101
    ruby_stack_upper_bound = upper;
2102
}
2103

  
2104
static void
2105
get_machine_stack_bounds(rb_thread_t *th, VALUE **stack_start, VALUE **stack_end, unsigned stack_end_increment)
2106
{
2107
#if STACK_GROW_DIRECTION < 0
2108
    *stack_start = th->machine_stack_end;
2109
    *stack_end = th->machine_stack_start;
2110
#elif STACK_GROW_DIRECTION > 0
2111
    *stack_start = th->machine_stack_start;
2112
    *stack_end = th->machine_stack_end + stack_end_increment;
2113
#else
2114
    if (th->machine_stack_end < th->machine_stack_start) {
2115
        *stack_start = th->machine_stack_end;
2116
        *stack_end = th->machine_stack_start;
2117
    }
2118
    else {
2119
        *stack_start = th->machine_stack_start;
2120
        *stack_end = th->machine_stack_end + stack_end_increment;
2121
    }
2122
#endif
2123

  
2124
    if (th == th->vm->main_thread) {
2125
        if (ruby_stack_lower_bound && *stack_start < ruby_stack_lower_bound) {
2126
          *stack_start = ruby_stack_lower_bound;
2127
        }
2128

  
2129
        if (ruby_stack_upper_bound && *stack_end > ruby_stack_upper_bound) {
2130
          *stack_end = ruby_stack_upper_bound;
2131
        }
2132
    }
2133
}
2134

  
2092 2135
static void
2093 2136
mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th)
2094 2137
{
......
2100 2143
    rb_setjmp(save_regs_gc_mark);
2101 2144

  
2102 2145
    SET_STACK_END;
2103
#if STACK_GROW_DIRECTION < 0
2104
    stack_start = th->machine_stack_end;
2105
    stack_end = th->machine_stack_start;
2106
#elif STACK_GROW_DIRECTION > 0
2107
    stack_start = th->machine_stack_start;
2108
    stack_end = th->machine_stack_end + 1;
2109
#else
2110
    if (th->machine_stack_end < th->machine_stack_start) {
2111
        stack_start = th->machine_stack_end;
2112
        stack_end = th->machine_stack_start;
2113
    }
2114
    else {
2115
        stack_start = th->machine_stack_start;
2116
        stack_end = th->machine_stack_end + 1;
2117
    }
2118
#endif
2146
    get_machine_stack_bounds(th, &stack_start, &stack_end, 1);
2119 2147

  
2120 2148
    mark_locations_array(objspace,
2121 2149
			 (VALUE*)save_regs_gc_mark,
......
2219 2247
void
2220 2248
rb_gc_mark_machine_stack(rb_thread_t *th)
2221 2249
{
2250
    VALUE *stack_start, *stack_end;
2251
    get_machine_stack_bounds(th, &stack_start, &stack_end, 0);
2252

  
2222 2253
    rb_objspace_t *objspace = &rb_objspace;
2223
#if STACK_GROW_DIRECTION < 0
2224
    rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
2225
#elif STACK_GROW_DIRECTION > 0
2226
    rb_gc_mark_locations(th->machine_stack_start, th->machine_stack_end);
2227
#else
2228
    if (th->machine_stack_start < th->machine_stack_end) {
2229
	rb_gc_mark_locations(th->machine_stack_start, th->machine_stack_end);
2230
    }
2231
    else {
2232
	rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
2233
    }
2234
#endif
2254
    rb_gc_mark_locations(stack_start, stack_end);
2255

  
2235 2256
#ifdef __ia64
2236 2257
    rb_gc_mark_locations(th->machine_register_stack_start, th->machine_register_stack_end);
2237 2258
#endif
include/ruby/ruby.h
1138 1138
#define RUBY_INIT_STACK \
1139 1139
    VALUE variable_in_this_stack_frame; \
1140 1140
    ruby_init_stack(&variable_in_this_stack_frame);
1141
/*
1142
 * Binds Ruby's stack to the region of memory that spans from the given
1143
 * "lower" boundary up to (but not including) the given "upper" boundary.
1144
 * Note that these boundaries _do not_ protect against stack overflow!
1145
 */
1146
void ruby_bind_stack(void *lower, void *upper);
1141 1147
void ruby_init(void);
1142 1148
void *ruby_options(int, char**);
1143 1149
int ruby_run_node(void *);
1144
-