bbgc.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #ifndef BB_GC_H
  2. #define BB_GC_H
  3. #include "bbstd.h"
  4. #include "bbtypes.h"
  5. #include "bbfunction.h"
  6. #ifndef NDEBUG
  7. #define BBGC_VALIDATE( P ) \
  8. if( (P) && ((P)->state!=0 && (P)->state!=1 && (P)->state!=2) ){ \
  9. printf( "BBGC_VALIDATE failed: %p %s %i\n",(P),(P)->typeName(),(P)->state ); \
  10. fflush( stdout ); \
  11. abort(); \
  12. }
  13. #else
  14. #define BBGC_VALIDATE( P )
  15. #endif
  16. struct bbGCNode;
  17. struct bbGCFiber;
  18. struct bbGCFrame;
  19. struct bbGCRoot;
  20. struct bbGCTmp;
  21. namespace bbGC{
  22. extern int markedBit;
  23. extern int unmarkedBit;
  24. extern bbGCRoot *roots;
  25. extern bbGCTmp *freeTmps;
  26. extern bbGCNode *markQueue;
  27. extern bbGCNode *unmarkedList;
  28. extern bbGCFiber *fibers;
  29. extern bbGCFiber *currentFiber;
  30. void init();
  31. void suspend();
  32. void resume();
  33. void retain( bbGCNode *p );
  34. void release( bbGCNode *p );
  35. void setDebug( bool debug );
  36. void setTrigger( size_t trigger );
  37. void *malloc( size_t size );
  38. size_t mallocSize( void *p );
  39. void free( void *p );
  40. void collect();
  41. // bbGCNode *alloc( size_t size );
  42. }
  43. struct bbGCNode{
  44. bbGCNode *succ;
  45. bbGCNode *pred;
  46. char pad[2];
  47. char state; //0=lonely, 1/2=marked/unmarked; 3=destroyed
  48. char flags; //1=finalize
  49. bbGCNode(){
  50. }
  51. void gcNeedsFinalize(){
  52. flags|=1;
  53. }
  54. virtual ~bbGCNode(){
  55. }
  56. virtual void gcFinalize(){
  57. }
  58. virtual void gcMark(){
  59. }
  60. virtual void dbEmit(){
  61. }
  62. virtual const char *typeName()const{
  63. return "bbGCNode";
  64. }
  65. };
  66. struct bbGCFiber{
  67. bbGCFiber *succ;
  68. bbGCFiber *pred;
  69. bbGCFrame *frames;
  70. bbGCNode *ctoring;
  71. bbGCTmp *tmps;
  72. bbFunction<void()> entry;
  73. bbGCFiber():succ( this ),pred( this ),frames( nullptr ),ctoring( nullptr ),tmps( nullptr ){
  74. }
  75. void link(){
  76. succ=bbGC::fibers;
  77. pred=bbGC::fibers->pred;
  78. bbGC::fibers->pred=this;
  79. pred->succ=this;
  80. }
  81. void unlink(){
  82. pred->succ=succ;
  83. succ->pred=pred;
  84. }
  85. };
  86. struct bbGCFrame{
  87. bbGCFrame *succ;
  88. bbGCFrame():succ( bbGC::currentFiber->frames ){
  89. bbGC::currentFiber->frames=this;
  90. }
  91. ~bbGCFrame(){
  92. bbGC::currentFiber->frames=succ;
  93. }
  94. virtual void gcMark(){
  95. }
  96. };
  97. struct bbGCRoot{
  98. bbGCRoot *succ;
  99. bbGCRoot():succ( bbGC::roots ){
  100. bbGC::roots=this;
  101. }
  102. virtual void gcMark(){
  103. }
  104. };
  105. struct bbGCTmp{
  106. bbGCTmp *succ;
  107. bbGCNode *node;
  108. };
  109. namespace bbGC{
  110. inline void insert( bbGCNode *p,bbGCNode *succ ){
  111. p->succ=succ;
  112. p->pred=succ->pred;
  113. p->pred->succ=p;
  114. succ->pred=p;
  115. }
  116. inline void remove( bbGCNode *p ){
  117. p->pred->succ=p->succ;
  118. p->succ->pred=p->pred;
  119. }
  120. inline void enqueue( bbGCNode *p ){
  121. BBGC_VALIDATE( p )
  122. if( !p || p->state!=unmarkedBit ) return;
  123. remove( p );
  124. p->succ=markQueue;
  125. markQueue=p;
  126. p->state=markedBit;
  127. }
  128. inline void pushTmp( bbGCNode *p ){
  129. BBGC_VALIDATE( p );
  130. bbGCTmp *tmp=freeTmps;
  131. if( !tmp ) tmp=new bbGCTmp;
  132. tmp->node=p;
  133. tmp->succ=currentFiber->tmps;
  134. currentFiber->tmps=tmp;
  135. }
  136. inline void popTmps( int n ){
  137. while( n-- ){
  138. bbGCTmp *tmp=currentFiber->tmps;
  139. currentFiber->tmps=tmp->succ;
  140. tmp->succ=freeTmps;
  141. freeTmps=tmp;
  142. }
  143. }
  144. template<class T> T *tmp( T *p ){
  145. pushTmp( p );
  146. return p;
  147. }
  148. inline void beginCtor( bbGCNode *p ){
  149. p->succ=currentFiber->ctoring;
  150. currentFiber->ctoring=p;
  151. p->state=0;
  152. p->flags=0;
  153. }
  154. inline void endCtor( bbGCNode *p ){
  155. currentFiber->ctoring=p->succ;
  156. p->succ=markQueue;
  157. markQueue=p;
  158. p->state=markedBit;
  159. }
  160. }
  161. template<class T> void bbGCMark( T const& ){
  162. }
  163. #endif