aboutsummaryrefslogblamecommitdiff
path: root/gc.cpp
blob: 0e4fc3d76973ee8c4925d1051168f732789f87b0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                   
                 
 
                 
                                          



                                   
                                          
                  
 
                                      


                                                      
                        
                                         

 



                                                                       
                                             
                                                   
               
                                                                
                                                                        
      
                                   
     
               
                                                            
      

                                                           



                                
                                                        

                     
                              
                                                
                       


                                                 
                         
 
              
                                          
                   




                                                  



                       

                                                                   

              














                                                            
              
                                                               
                           
                                                                 


               




                                                 
                                     

                             
      
                          

                                                                 
                                                                    
      

                                              


                                  
                                        
                                 



                                                               
         

                                                                    

                            
     



                                                  
 
                                                  
                                                   
                      
 



                                                   
                         




                                                  



                                             



                                  
                                          



                        
 

                                          
                       




                                                                
 







                                                     


                                           





                              
 


                                                      
#include "gc.h"
#include "exc.h"
#include "consts.h"
#include <vector>

#include <cstdio>
#if defined(GC_DEBUG) || defined (GC_INFO)
typedef unsigned long long ull;
#endif

static EvalObj *gcq[GC_QUEUE_SIZE];
static Container *cyc_list[GC_QUEUE_SIZE];
ObjEntry *oe_null;

GarbageCollector::GarbageCollector() {
    joined = new ObjEntry(NULL, NULL);
    joined->next = oe_null = new ObjEntry(NULL, NULL);
    joined_size = 0;
    pending_list = NULL;
    resolve_threshold = GC_CYC_THRESHOLD;
}

GarbageCollector::PendingEntry::PendingEntry(
        EvalObj *_obj, PendingEntry *_next) : obj(_obj), next(_next) {}


void GarbageCollector::expose(EvalObj *ptr) {
    if (ptr == NULL || ptr->gc_obj == NULL) return;
#ifdef GC_DEBUG
    fprintf(stderr, "GC: 0x%llx exposed. count = %lu \"%s\"\n", 
            (ull)ptr, ptr->gc_obj->gc_cnt - 1, ptr->ext_repr().c_str());
#endif
    if (--ptr->gc_obj->gc_cnt == 0)
    {
#ifdef GC_DEBUG
        fprintf(stderr, "GC: 0x%llx pending. \n", (ull)ptr);
#endif
        pending_list = new PendingEntry(ptr, pending_list);
    } 
}

void GarbageCollector::force() {
    EvalObj **l = gcq, **r = l;
    for (PendingEntry *p = pending_list, *np; p; p = np)
    {
        np = p->next;
        EvalObj *obj = p->obj;
        if (obj->gc_obj && !obj->gc_obj->gc_cnt)
            *r++ = obj;
        delete p;
    }   // fetch the pending pointers in the list
    // clear the list
    pending_list = NULL; 

#ifdef GC_INFO
    fprintf(stderr, "%ld\n", joined_size);
    size_t cnt = 0;
#endif
#ifdef GC_DEBUG
    fprintf(stderr, 
            "================================\n"
            "GC: Forcing the clear process...\n");
#endif
    for (; l != r; l++)
    {
#ifdef GC_DEBUG
        fprintf(stderr, "GC: !!! destroying space 0x%llx: %s. \n", 
                (ull)*l, (*l)->ext_repr().c_str());
#endif
#ifdef GC_INFO
        cnt++;
#endif
        delete *l;
        // maybe it's a complex structure, 
        // so that more pointers are reported
        for (PendingEntry *p = pending_list, *np; p; p = np)
        {
            np = p->next;
            *r++ =