root/Zend/zend_gc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. gc_check_possible_root

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: David Wang <planetbeing@gmail.com>                          |
  16    |          Dmitry Stogov <dmitry@zend.com>                             |
  17    +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #ifndef ZEND_GC_H
  23 #define ZEND_GC_H
  24 
  25 #ifndef GC_BENCH
  26 # define GC_BENCH 0
  27 #endif
  28 
  29 #if GC_BENCH
  30 # define GC_BENCH_INC(counter) GC_G(counter)++
  31 # define GC_BENCH_DEC(counter) GC_G(counter)--
  32 # define GC_BENCH_PEAK(peak, counter) do {              \
  33                 if (GC_G(counter) > GC_G(peak)) {               \
  34                         GC_G(peak) = GC_G(counter);                     \
  35                 }                                                                               \
  36         } while (0)
  37 #else
  38 # define GC_BENCH_INC(counter)
  39 # define GC_BENCH_DEC(counter)
  40 # define GC_BENCH_PEAK(peak, counter)
  41 #endif
  42 
  43 #define GC_COLOR  0xc000
  44 
  45 #define GC_BLACK  0x0000
  46 #define GC_WHITE  0x8000
  47 #define GC_GREY   0x4000
  48 #define GC_PURPLE 0xc000
  49 
  50 #define GC_ADDRESS(v) \
  51         ((v) & ~GC_COLOR)
  52 #define GC_INFO_GET_COLOR(v) \
  53         (((zend_uintptr_t)(v)) & GC_COLOR)
  54 #define GC_INFO_SET_ADDRESS(v, a) \
  55         do {(v) = ((v) & GC_COLOR) | (a);} while (0)
  56 #define GC_INFO_SET_COLOR(v, c) \
  57         do {(v) = ((v) & ~GC_COLOR) | (c);} while (0)
  58 #define GC_INFO_SET_BLACK(v) \
  59         do {(v) = (v) & ~GC_COLOR;} while (0)
  60 #define GC_INFO_SET_PURPLE(v) \
  61         do {(v) = (v) | GC_COLOR;} while (0)
  62 
  63 typedef struct _gc_root_buffer {
  64         zend_refcounted          *ref;
  65         struct _gc_root_buffer   *next;     /* double-linked list               */
  66         struct _gc_root_buffer   *prev;
  67         uint32_t                 refcount;
  68 } gc_root_buffer;
  69 
  70 typedef struct _zend_gc_globals {
  71         zend_bool         gc_enabled;
  72         zend_bool         gc_active;
  73         zend_bool         gc_full;
  74 
  75         gc_root_buffer   *buf;                          /* preallocated arrays of buffers   */
  76         gc_root_buffer    roots;                        /* list of possible roots of cycles */
  77         gc_root_buffer   *unused;                       /* list of unused buffers           */
  78         gc_root_buffer   *first_unused;         /* pointer to first unused buffer   */
  79         gc_root_buffer   *last_unused;          /* pointer to last unused buffer    */
  80 
  81         gc_root_buffer    to_free;                      /* list to free                     */
  82         gc_root_buffer   *next_to_free;
  83 
  84         uint32_t gc_runs;
  85         uint32_t collected;
  86 
  87 #if GC_BENCH
  88         uint32_t root_buf_length;
  89         uint32_t root_buf_peak;
  90         uint32_t zval_possible_root;
  91         uint32_t zval_buffered;
  92         uint32_t zval_remove_from_buffer;
  93         uint32_t zval_marked_grey;
  94 #endif
  95 
  96 } zend_gc_globals;
  97 
  98 #ifdef ZTS
  99 BEGIN_EXTERN_C()
 100 ZEND_API extern int gc_globals_id;
 101 END_EXTERN_C()
 102 #define GC_G(v) ZEND_TSRMG(gc_globals_id, zend_gc_globals *, v)
 103 #else
 104 #define GC_G(v) (gc_globals.v)
 105 extern ZEND_API zend_gc_globals gc_globals;
 106 #endif
 107 
 108 BEGIN_EXTERN_C()
 109 ZEND_API extern int (*gc_collect_cycles)(void);
 110 
 111 ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref);
 112 ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref);
 113 ZEND_API void gc_globals_ctor(void);
 114 ZEND_API void gc_globals_dtor(void);
 115 ZEND_API void gc_init(void);
 116 ZEND_API void gc_reset(void);
 117 
 118 /* The default implementation of the gc_collect_cycles callback. */
 119 ZEND_API int  zend_gc_collect_cycles(void);
 120 END_EXTERN_C()
 121 
 122 #define GC_ZVAL_CHECK_POSSIBLE_ROOT(z) \
 123         gc_check_possible_root((z))
 124 
 125 #define GC_REMOVE_FROM_BUFFER(p) do { \
 126                 zend_refcounted *_p = (zend_refcounted*)(p); \
 127                 if (GC_ADDRESS(GC_INFO(_p))) { \
 128                         gc_remove_from_buffer(_p); \
 129                 } \
 130         } while (0)
 131 
 132 static zend_always_inline void gc_check_possible_root(zval *z)
 133 {
 134         ZVAL_DEREF(z);
 135         if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
 136                 gc_possible_root(Z_COUNTED_P(z));
 137         }
 138 }
 139 
 140 #endif /* ZEND_GC_H */
 141 
 142 /*
 143  * Local variables:
 144  * tab-width: 4
 145  * c-basic-offset: 4
 146  * indent-tabs-mode: t
 147  * End:
 148  */

/* [<][>][^][v][top][bottom][index][help] */