Changes between Version 2 and Version 3 of GCMassacre

Show
Ignore:
Timestamp:
05/25/10 11:19:06 (12 years ago)
Author:
bacek
Comment:

Add "Non-recursive, tri-colour, incremental mark and sweep." proto

Legend:

Unmodified
Added
Removed
Modified
  • GCMassacre

    v2 v3  
    1919 
    2020{{{ 
     21#!perl 
    2122# GC don't care how this work. Pools/Arenas/Blocks/whatever. 
    2223class Allocator { 
     
    184185 
    185186 
     187# Non-recursive, tri-colour, incremental mark and sweep. 
     188class IncrementalTriColourGC is GC { 
     189    has @live_objects;  # Black 
     190    has @grey_objects;  # Guess? 
     191    has @dead_objects;  # White 
     192 
     193    has $do_marking;    # We are in mark phase. 
     194    has $do_sweeping;   # We are in sweep phase. 
     195 
     196    method need_gc() { 
     197        return Bool::False if self.do_marking || self.do_sweeping; 
     198        return self.SUPER.need_gc(); 
     199    } 
     200 
     201    method get_object() { 
     202        self.mark_a_little_bit() if self.do_marking; 
     203        self.sweep_a_little_bit() if self.do_sweeping; 
     204        self.SUPER.get_object(); 
     205    } 
     206 
     207    method do_gc() { 
     208        # Prepare mark phase 
     209        self.do_marking    = Bool::True; 
     210        self.do_sweeping   = Bool::False; 
     211        self.dead_objects  = self.objects; 
     212        self.objects       = (); 
     213 
     214        self.grey_objects  = self.trace_roots(); 
     215    } 
     216 
     217    method mark_a_little_bit() { 
     218        my $count = 0; 
     219        while(my $obj = self.grey_objects.pop) { 
     220            self.mark_real($obj); 
     221            return if $count++ > 10; 
     222        } 
     223 
     224        # Switch to incremental sweep. 
     225        self.do_marking  = Bool::False; 
     226        self.do_sweeping = Bool::True; 
     227    } 
     228 
     229    method sweep_a_little_bit() { 
     230        my $count = 0; 
     231        while(my $dead = self.dead_objects.pop) { 
     232            $dead.destroy(); 
     233            self.allocator.free($dead); 
     234            return if $count++ > 10; 
     235        } 
     236 
     237        # self.objects can be updated at this point of time. 
     238        # Add live_objects to objects to use on next GC round. 
     239        self.objects.push(self.live_objects); 
     240 
     241        # .grey_objects .dead_objects are empty now. 
     242        # Back to normal life 
     243        self.do_sweeping = Bool::False; 
     244    } 
     245 
     246    method mark_alive($obj) { 
     247        self.dead_objects.remove($obj); 
     248        self.grey_objects.push($obj); 
     249    } 
     250 
     251    method mark_real($obj) { 
     252        self.live_objects.push($obj); 
     253        self.SUPER.mark_alive($obj); 
     254    } 
     255}; 
     256 
     257 
     258 
    186259 
    187260# vim: ft=perl6