Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 326 lines (274 sloc) 10.699 kB
817a62d 2000-05-01
matz authored
1 /**********************************************************************
07bb9f2 1.4.0
matz authored
2
3 rubysig.h -
4
5 $Author$
6 $Date$
7 created at: Wed Aug 16 01:15:38 JST 1995
8
42bc5d2 Updated Copyrights of Matz to 2003.
michal authored
9 Copyright (C) 1993-2003 Yukihiro Matsumoto
817a62d 2000-05-01
matz authored
10
11 **********************************************************************/
12
07bb9f2 1.4.0
matz authored
13 #ifndef SIG_H
14 #define SIG_H
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
15
ece237c * lib/irb/ruby-lex.rb (RubyLex::identify_string): %s string do not
matz authored
16 #include <errno.h>
07bb9f2 1.4.0
matz authored
17
2ea481b @brentr #defined __anyPowerPC__
authored
18 #if defined __ppc__ || defined __powerpc__ || \
19 defined __ppc64__ || defined __powerpc64__
20 #define __anyPowerPC__ 1 /* for compatibility with older gcc versions */
21 #endif
22
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
23 /* STACK_WIPE_SITES determines where attempts are made to exorcise
24 "ghost object refereces" from the stack and how the stack is cleared:
25
26 0x*001 --> wipe stack just after every thread_switch
27 0x*002 --> wipe stack just after every EXEC_TAG()
28 0x*004 --> wipe stack in CHECK_INTS
29 0x*010 --> wipe stack in while & until loops
30 0x*020 --> wipe stack before yield() in iterators and outside eval.c
31 0x*040 --> wipe stack on catch and thread save context
32 0x*100 --> update stack extent on each object allocation
33 0x*200 --> update stack extent on each object reallocation
34 0x*400 --> update stack extent during GC marking passes
35 0x*800 --> update stack extent on each throw (use with 0x040)
36 0x1000 --> use inline assembly code for x86, PowerPC, or ARM CPUs
37
38 0x0*** --> do not even call rb_wipe_stack()
39 0x2*** --> call dummy rb_wipe_stack() (for debugging and profiling)
40 0x4*** --> safe, portable stack clearing in memory allocated with alloca
41 0x6*** --> use faster, but less safe stack clearing in unallocated stack
42 0x8*** --> use faster, but less safe stack clearing (with inline code)
43
44 for most effective gc use 0x*707
45 for fastest micro-benchmarking use 0x0000
46 0x*770 prevents almost all memory leaks caused by ghost references
47 without adding much overhead for stack clearing.
48 Other good trade offs are 0x*270, 0x*703, 0x*303 or even 0x*03
49
50 In general, you may lessen the default -mpreferred-stack-boundary
51 only if using less safe stack clearing (0x6***). Lessening the
52 stack alignment with portable stack clearing (0x4***) may fail to clear
53 all ghost references off the stack.
54
55 When using 0x6*** or 0x8***, the compiler could insert
56 stack push(s) between reading the stack pointer and clearing
57 the ghost references. The register(s) pushed will be
58 cleared by the rb_gc_stack_wipe(), typically resulting in a segfault
59 or an interpreter hang.
60
61 STACK_WIPE_SITES of 0x8770 works well compiled with gcc on most machines
62 using the recommended CFLAGS="-O2 -fno-stack-protector". However...
63 If it hangs or crashes for you, try changing STACK_WIPE_SITES to 0x4770
64 and please report your details. i.e. CFLAGS, compiler, version, CPU
65
66 Note that it is redundant to wipe_stack in looping constructs if
67 also doing so in CHECK_INTS. It is also redundant to wipe_stack on
68 each thread_switch if wiping after every thread save context.
69 */
70 #ifndef STACK_WIPE_SITES
71 # ifdef __x86_64__ /* deal with "red zone" by not inlining stack clearing */
72 # define STACK_WIPE_SITES 0x6770
2ea481b @brentr #defined __anyPowerPC__
authored
73 # elif defined __anyPowerPC__ /* On any PowerPC, deal with... */
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
74 # define STACK_WIPE_SITES 0x7764 /* red zone & alloc(0) doesn't return sp */
75 # else
76 # define STACK_WIPE_SITES 0x8770 /*normal case, use 0x4770 if problems arise*/
77 # endif
78 #endif
79
80 #if (STACK_WIPE_SITES & 0x14) == 0x14
81 #warning wiping stack in CHECK_INTS makes wiping in loops redundant
82 #endif
83 #if (STACK_WIPE_SITES & 0x41) == 0x41
84 #warning wiping stack after thread save makes wiping on thread_switch redundant
85 #endif
86
87 #define STACK_WIPE_METHOD (STACK_WIPE_SITES>>13)
88
8a5578c * configure.in, defines.h, dir.c, dir.h, dln.c, error.c,
uema2 authored
89 #ifdef _WIN32
757a5f3 matz
matz authored
90 typedef LONG rb_atomic_t;
91
92 # define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)
93 # define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
94 # define ATOMIC_INC(var) InterlockedIncrement(&(var))
95 # define ATOMIC_DEC(var) InterlockedDecrement(&(var))
96
97 /* Windows doesn't allow interrupt while system calls */
87de7d6 @unak * win32/win32.c: fasten file I/O on mswin32/mingw32.
unak authored
98 # define TRAP_BEG do {\
ece237c * lib/irb/ruby-lex.rb (RubyLex::identify_string): %s string do not
matz authored
99 int saved_errno = 0;\
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
100 rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1)
101 # define TRAP_END\
ece237c * lib/irb/ruby-lex.rb (RubyLex::identify_string): %s string do not
matz authored
102 ATOMIC_SET(rb_trap_immediate, trap_immediate);\
103 saved_errno = errno;\
104 CHECK_INTS;\
105 errno = saved_errno;\
87de7d6 @unak * win32/win32.c: fasten file I/O on mswin32/mingw32.
unak authored
106 } while (0)
757a5f3 matz
matz authored
107 # define RUBY_CRITICAL(statements) do {\
883206e Wed May 29 18:55:47 2002 KONISHI Hiromasa <H_Konishi@ruby-lang.org>
H_Konishi authored
108 rb_w32_enter_critical();\
757a5f3 matz
matz authored
109 statements;\
883206e Wed May 29 18:55:47 2002 KONISHI Hiromasa <H_Konishi@ruby-lang.org>
H_Konishi authored
110 rb_w32_leave_critical();\
757a5f3 matz
matz authored
111 } while (0)
8b6e94a matz
matz authored
112 #else
757a5f3 matz
matz authored
113 typedef int rb_atomic_t;
114
115 # define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)
116 # define ATOMIC_SET(var, val) ((var) = (val))
117 # define ATOMIC_INC(var) (++(var))
118 # define ATOMIC_DEC(var) (--(var))
119
5a3fb9f matz
matz authored
120 # define TRAP_BEG do {\
39a6108 @nobu * rubysig.h (TRAP_BEG, TRAP_END): safe errno around CHECK_INTS.
nobu authored
121 int saved_errno = 0;\
5a3fb9f matz
matz authored
122 int trap_immediate = rb_trap_immediate;\
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
123 rb_trap_immediate = 1
5a3fb9f matz
matz authored
124 # define TRAP_END rb_trap_immediate = trap_immediate;\
39a6108 @nobu * rubysig.h (TRAP_BEG, TRAP_END): safe errno around CHECK_INTS.
nobu authored
125 saved_errno = errno;\
126 CHECK_INTS;\
127 errno = saved_errno;\
5a3fb9f matz
matz authored
128 } while (0)
129
757a5f3 matz
matz authored
130 # define RUBY_CRITICAL(statements) do {\
131 int trap_immediate = rb_trap_immediate;\
132 rb_trap_immediate = 0;\
133 statements;\
134 rb_trap_immediate = trap_immediate;\
135 } while (0)
8b6e94a matz
matz authored
136 #endif
23b715b @nobu * configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define
nobu authored
137 RUBY_EXTERN rb_atomic_t rb_trap_immediate;
07bb9f2 1.4.0
matz authored
138
23b715b @nobu * configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define
nobu authored
139 RUBY_EXTERN int rb_prohibit_interrupt;
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
140 #define DEFER_INTS (rb_prohibit_interrupt++)
141 #define ALLOW_INTS do {\
142 rb_prohibit_interrupt--;\
143 CHECK_INTS;\
144 } while (0)
145 #define ENABLE_INTS (rb_prohibit_interrupt--)
07bb9f2 1.4.0
matz authored
146
7678f4b * eval.c (block_pass): should not downgrade safe level.
matz authored
147 VALUE rb_with_disable_interrupt _((VALUE(*)(ANYARGS),VALUE));
07bb9f2 1.4.0
matz authored
148
23b715b @nobu * configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define
nobu authored
149 RUBY_EXTERN rb_atomic_t rb_trap_pending;
07bb9f2 1.4.0
matz authored
150 void rb_trap_restore_mask _((void));
151
23b715b @nobu * configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define
nobu authored
152 RUBY_EXTERN int rb_thread_critical;
07bb9f2 1.4.0
matz authored
153 void rb_thread_schedule _((void));
b9743ef @brentr MBARI 3
authored
154
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
155 RUBY_EXTERN VALUE *rb_gc_stack_end;
156 RUBY_EXTERN int rb_gc_stack_grow_direction; /* -1 for down or 1 for up */
b9743ef @brentr MBARI 3
authored
157
158 #if STACK_GROW_DIRECTION > 0
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
159
160 /* clear stack space between end and sp (not including *sp) */
b9743ef @brentr MBARI 3
authored
161 #define __stack_zero(end,sp) __stack_zero_up(end,sp)
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
162
163 /* true if top has grown past limit, i.e. top deeper than limit */
164 #define __stack_past(limit,top) __stack_past_up(limit,top)
165
166 /* depth of mid below stack top */
167 #define __stack_depth(top,mid) __stack_depth_up(top,mid)
168
169 /* stack pointer top adjusted to include depth more items */
170 #define __stack_grow(top,depth) __stack_grow_up(top,depth)
171
172
b9743ef @brentr MBARI 3
authored
173 #elif STACK_GROW_DIRECTION < 0
174 #define __stack_zero(end,sp) __stack_zero_down(end,sp)
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
175 #define __stack_past(limit,top) __stack_past_down(limit,top)
176 #define __stack_depth(top,mid) __stack_depth_down(top,mid)
177 #define __stack_grow(top,depth) __stack_grow_down(top,depth)
178
b9743ef @brentr MBARI 3
authored
179 #else /* limp along if stack direction can't be determined at compile time */
180 #define __stack_zero(end,sp) if (rb_gc_stack_grow_direction<0) \
181 __stack_zero_down(end,sp); else __stack_zero_up(end,sp);
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
182 #define __stack_past(limit,top) (rb_gc_stack_grow_direction<0 ? \
183 __stack_past_down(limit,top) : __stack_past_up(limit,top))
184 #define __stack_depth(top,mid) (rb_gc_stack_grow_direction<0 ? \
185 __stack_depth_down(top,mid) : __stack_depth_up(top,mid))
186 #define __stack_grow(top,depth) (rb_gc_stack_grow_direction<0 ? \
187 __stack_grow_down(top,depth) : __stack_grow_up(top,depth))
b9743ef @brentr MBARI 3
authored
188 #endif
189
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
190 #define __stack_zero_up(end,sp) while (end >= ++sp) *sp=0
191 #define __stack_past_up(limit,top) ((limit) < (top))
192 #define __stack_depth_up(top,mid) ((top) - (mid))
193 #define __stack_grow_up(top,depth) ((top)+(depth))
194
195 #define __stack_zero_down(end,sp) while (end <= --sp) *sp=0
196 #define __stack_past_down(limit,top) ((limit) > (top))
197 #define __stack_depth_down(top,mid) ((mid) - (top))
198 #define __stack_grow_down(top,depth) ((top)-(depth))
199
200 /* Make alloca work the best possible way. */
201 #ifdef __GNUC__
202 # ifndef atarist
203 # ifndef alloca
204 # define alloca __builtin_alloca
205 # endif
206 # endif /* atarist */
207
208 # define nativeAllocA __builtin_alloca
209
210 /* use assembly to get stack pointer quickly */
211 # if STACK_WIPE_SITES & 0x1000
212 # define __defspfn(asmb) \
213 static inline VALUE *__sp(void) __attribute__((always_inline)); \
214 static inline VALUE *__sp(void) \
215 { \
216 VALUE *sp; asm(asmb); \
217 return sp; \
218 }
2ea481b @brentr #defined __anyPowerPC__
authored
219 # ifdef __anyPowerPC__
8442091 @brentr assume non-Apple gcc on PowerPC is not using -mregnames
authored
220 # ifdef __APPLE__
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
221 __defspfn("addi %0, r1, 0": "=r"(sp))
8442091 @brentr assume non-Apple gcc on PowerPC is not using -mregnames
authored
222 # else
223 __defspfn("addi %0, 1, 0": "=r"(sp))
224 # endif
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
225 # elif defined __i386__
226 __defspfn("movl %%esp, %0": "=r"(sp))
227 # elif defined __x86_64__
79ae1d7 @brentr added --with-wipe-sites= & --enable-mbari-api.
authored
228 #warn ===> x86_64 inline assembler is known to crash -- change STACK_WIPE_SITES
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
229 __defspfn("movq %%rsp, %0": "=r"(sp))
230 # elif __arm__
231 __defspfn("mov %0, sp": "=r"(sp))
232 # else
233 # define __sp() ((VALUE *)__builtin_alloca(0))
234 # warning No assembly version of __sp() defined for this CPU.
235 # endif
236 # else
237 # define __sp() ((VALUE *)__builtin_alloca(0))
238 # endif
239
240 #else // not GNUC
241
242 # ifdef HAVE_ALLOCA_H
243 # include <alloca.h>
244 # else
245 # ifndef _AIX
246 # ifndef alloca /* predefined by HP cc +Olibcalls */
247 void *alloca ();
248 # endif
249 # endif /* AIX */
250 # endif /* HAVE_ALLOCA_H */
251
252 # if STACK_WIPE_SITES & 0x1000
253 # warning No assembly versions of __sp() defined for this compiler.
254 # endif
255 # if HAVE_ALLOCA
256 # define __sp() ((VALUE *)alloca(0))
257 # define nativeAllocA alloca
258 # else
259 RUBY_EXTERN VALUE *__sp(void);
260 # if STACK_WIPE_SITES
261 # define STACK_WIPE_SITES 0
262 # warning Disabled Stack Wiping because there is no native alloca()
263 # endif
264 # endif
265 #endif /* __GNUC__ */
266
267
b9743ef @brentr MBARI 3
authored
268 /*
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
269 Zero memory that was (recently) part of the stack, but is no longer.
270 Invoke when stack is deep to mark its extent and when it's shallow to wipe it.
b9743ef @brentr MBARI 3
authored
271 */
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
272 #if STACK_WIPE_METHOD == 0
273 #define rb_gc_wipe_stack() ((void)0)
274 #elif STACK_WIPE_METHOD == 4
b9743ef @brentr MBARI 3
authored
275 #define rb_gc_wipe_stack() { \
276 VALUE *end = rb_gc_stack_end; \
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
277 VALUE *sp = __sp(); \
b9743ef @brentr MBARI 3
authored
278 rb_gc_stack_end = sp; \
279 __stack_zero(end, sp); \
280 }
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
281 #else
282 RUBY_EXTERN void rb_gc_wipe_stack(void);
283 #endif
b9743ef @brentr MBARI 3
authored
284
285 /*
286 Update our record of maximum stack extent without zeroing unused stack
287 */
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
288 #define rb_gc_update_stack_extent() do { \
289 VALUE *sp = __sp(); \
290 if __stack_past(rb_gc_stack_end, sp) rb_gc_stack_end = sp; \
291 } while(0)
b9743ef @brentr MBARI 3
authored
292
293
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
294 #if STACK_WIPE_SITES & 4
295 # define CHECK_INTS_wipe_stack() rb_gc_wipe_stack()
296 #else
297 # define CHECK_INTS_wipe_stack() (void)0
298 #endif
299
300 #if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
301 RUBY_EXTERN int rb_thread_pending;
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
302 # define CHECK_INTS do {\
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
303 CHECK_INTS_wipe_stack(); \
e9950cd * rubysig.h (CHECK_INTS): fixed typo. (I believe bit-or is improper)
ocean authored
304 if (!(rb_prohibit_interrupt || rb_thread_critical)) {\
013deca * rubysig.h (CHECK_INTS): prevent signal handler to run during
matz authored
305 if (rb_thread_pending) rb_thread_schedule();\
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
306 if (rb_trap_pending) rb_trap_exec();\
307 }\
308 } while (0)
07bb9f2 1.4.0
matz authored
309 #else
310 /* pseudo preemptive thread switching */
23b715b @nobu * configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define
nobu authored
311 RUBY_EXTERN int rb_thread_tick;
07bb9f2 1.4.0
matz authored
312 #define THREAD_TICK 500
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
313 #define CHECK_INTS do {\
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
314 CHECK_INTS_wipe_stack(); \
e9950cd * rubysig.h (CHECK_INTS): fixed typo. (I believe bit-or is improper)
ocean authored
315 if (!(rb_prohibit_interrupt || rb_thread_critical)) {\
013deca * rubysig.h (CHECK_INTS): prevent signal handler to run during
matz authored
316 if (rb_thread_tick-- <= 0) {\
2b78bc2 @unak * rubysig.h (CHECK_INTS): fix typo.
unak authored
317 rb_thread_tick = THREAD_TICK;\
318 rb_thread_schedule();\
07bb9f2 1.4.0
matz authored
319 }\
c00ced6 @brentr MBARI 7- -- speed tweaks and configuration options
authored
320 if (rb_trap_pending) rb_trap_exec();\
07bb9f2 1.4.0
matz authored
321 }\
d53d108 * io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.
matz authored
322 } while (0)
07bb9f2 1.4.0
matz authored
323 #endif
324
325 #endif
Something went wrong with that request. Please try again.