Ruby  2.0.0p247(2013-06-27revision41674)
gc.h
Go to the documentation of this file.
00001 
00002 #ifndef RUBY_GC_H
00003 #define RUBY_GC_H 1
00004 
00005 #if defined(__x86_64__) && defined(__GNUC__) && !defined(__native_client__)
00006 #define SET_MACHINE_STACK_END(p) __asm__ volatile ("movq\t%%rsp, %0" : "=r" (*(p)))
00007 #elif defined(__i386) && defined(__GNUC__) && !defined(__native_client__)
00008 #define SET_MACHINE_STACK_END(p) __asm__ volatile ("movl\t%%esp, %0" : "=r" (*(p)))
00009 #else
00010 NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
00011 #define SET_MACHINE_STACK_END(p) rb_gc_set_stack_end(p)
00012 #define USE_CONSERVATIVE_STACK_END
00013 #endif
00014 
00015 /* for GC debug */
00016 
00017 #ifndef RUBY_MARK_FREE_DEBUG
00018 #define RUBY_MARK_FREE_DEBUG 0
00019 #endif
00020 
00021 #if RUBY_MARK_FREE_DEBUG
00022 extern int ruby_gc_debug_indent;
00023 
00024 static inline void
00025 rb_gc_debug_indent(void)
00026 {
00027     printf("%*s", ruby_gc_debug_indent, "");
00028 }
00029 
00030 static inline void
00031 rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
00032 {
00033     if (st == 0) {
00034         ruby_gc_debug_indent--;
00035     }
00036     rb_gc_debug_indent();
00037     printf("%s: %s %s (%p)\n", mode, st ? "->" : "<-", msg, ptr);
00038 
00039     if (st) {
00040         ruby_gc_debug_indent++;
00041     }
00042 
00043     fflush(stdout);
00044 }
00045 
00046 #define RUBY_MARK_ENTER(msg) rb_gc_debug_body("mark", (msg), 1, ptr)
00047 #define RUBY_MARK_LEAVE(msg) rb_gc_debug_body("mark", (msg), 0, ptr)
00048 #define RUBY_FREE_ENTER(msg) rb_gc_debug_body("free", (msg), 1, ptr)
00049 #define RUBY_FREE_LEAVE(msg) rb_gc_debug_body("free", (msg), 0, ptr)
00050 #define RUBY_GC_INFO         rb_gc_debug_indent(); printf
00051 
00052 #else
00053 #define RUBY_MARK_ENTER(msg)
00054 #define RUBY_MARK_LEAVE(msg)
00055 #define RUBY_FREE_ENTER(msg)
00056 #define RUBY_FREE_LEAVE(msg)
00057 #define RUBY_GC_INFO if(0)printf
00058 #endif
00059 
00060 #define RUBY_MARK_UNLESS_NULL(ptr) if(RTEST(ptr)){rb_gc_mark(ptr);}
00061 #define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}
00062 
00063 #if STACK_GROW_DIRECTION > 0
00064 # define STACK_UPPER(x, a, b) (a)
00065 #elif STACK_GROW_DIRECTION < 0
00066 # define STACK_UPPER(x, a, b) (b)
00067 #else
00068 RUBY_EXTERN int ruby_stack_grow_direction;
00069 int ruby_get_stack_grow_direction(volatile VALUE *addr);
00070 # define stack_growup_p(x) (                    \
00071         (ruby_stack_grow_direction ?            \
00072          ruby_stack_grow_direction :            \
00073          ruby_get_stack_grow_direction(x)) > 0)
00074 # define STACK_UPPER(x, a, b) (stack_growup_p(x) ? (a) : (b))
00075 #endif
00076 
00077 #if STACK_GROW_DIRECTION
00078 #define STACK_GROW_DIR_DETECTION
00079 #define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
00080 #else
00081 #define STACK_GROW_DIR_DETECTION VALUE stack_grow_dir_detection
00082 #define STACK_DIR_UPPER(a,b) STACK_UPPER(&stack_grow_dir_detection, (a), (b))
00083 #endif
00084 #define IS_STACK_DIR_UPPER() STACK_DIR_UPPER(1,0)
00085 
00086 #if defined __GNUC__ && __GNUC__ >= 4
00087 #pragma GCC visibility push(default)
00088 #endif
00089 
00090 /* exports for objspace module */
00091 size_t rb_objspace_data_type_memsize(VALUE obj);
00092 void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
00093 int rb_objspace_markable_object_p(VALUE obj);
00094 int rb_objspace_internal_object_p(VALUE obj);
00095 
00096 void rb_objspace_each_objects(
00097     int (*callback)(void *start, void *end, size_t stride, void *data),
00098     void *data);
00099 
00100 #if defined __GNUC__ && __GNUC__ >= 4
00101 #pragma GCC visibility pop
00102 #endif
00103 
00104 #endif /* RUBY_GC_H */
00105