Beispiel #1
0
    def __init__(self, config,
                 nursery_size=32*WORD,
                 min_nursery_size=32*WORD,
                 auto_nursery_size=False,
                 space_size=1024*WORD,
                 max_space_size=sys.maxint//2+1,
                 **kwds):
        SemiSpaceGC.__init__(self, config,
                             space_size = space_size,
                             max_space_size = max_space_size,
                             **kwds)
        assert min_nursery_size <= nursery_size <= space_size // 2
        self.initial_nursery_size = nursery_size
        self.auto_nursery_size = auto_nursery_size
        self.min_nursery_size = min_nursery_size

        # define nursery fields
        self.reset_nursery()
        self._setup_wb()

        # compute the constant lower bounds for the attributes
        # largest_young_fixedsize and largest_young_var_basesize.
        # It is expected that most (or all) objects have a fixedsize
        # that is much lower anyway.
        sz = self.get_young_fixedsize(self.min_nursery_size)
        self.lb_young_fixedsize = sz
        sz = self.get_young_var_basesize(self.min_nursery_size)
        self.lb_young_var_basesize = sz
Beispiel #2
0
    def __init__(self, config,
                 nursery_size=32*WORD,
                 min_nursery_size=32*WORD,
                 auto_nursery_size=False,
                 space_size=1024*WORD,
                 max_space_size=sys.maxint//2+1,
                 **kwds):
        SemiSpaceGC.__init__(self, config,
                             space_size = space_size,
                             max_space_size = max_space_size,
                             **kwds)
        assert min_nursery_size <= nursery_size <= space_size // 2
        self.initial_nursery_size = nursery_size
        self.auto_nursery_size = auto_nursery_size
        self.min_nursery_size = min_nursery_size

        # define nursery fields
        self.reset_nursery()
        self._setup_wb()

        # compute the constant lower bounds for the attributes
        # largest_young_fixedsize and largest_young_var_basesize.
        # It is expected that most (or all) objects have a fixedsize
        # that is much lower anyway.
        sz = self.get_young_fixedsize(self.min_nursery_size)
        self.lb_young_fixedsize = sz
        sz = self.get_young_var_basesize(self.min_nursery_size)
        self.lb_young_var_basesize = sz
Beispiel #3
0
 def debug_check_consistency(self):
     if self.DEBUG:
         self._d_oopty = self.old_objects_pointing_to_young.stack2dict()
         self._d_lgro = self.last_generation_root_objects.stack2dict()
         SemiSpaceGC.debug_check_consistency(self)
         self._d_oopty.delete()
         self._d_lgro.delete()
         self.old_objects_pointing_to_young.foreach(
             self._debug_check_flag_1, None)
         self.last_generation_root_objects.foreach(
             self._debug_check_flag_2, None)
Beispiel #4
0
 def debug_check_consistency(self):
     if self.DEBUG:
         self._d_oopty = self.old_objects_pointing_to_young.stack2dict()
         self._d_lgro = self.last_generation_root_objects.stack2dict()
         SemiSpaceGC.debug_check_consistency(self)
         self._d_oopty.delete()
         self._d_lgro.delete()
         self.old_objects_pointing_to_young.foreach(
             self._debug_check_flag_1, None)
         self.last_generation_root_objects.foreach(
             self._debug_check_flag_2, None)
Beispiel #5
0
 def malloc_fixedsize_clear(self, typeid, size,
                            has_finalizer=False,
                            is_finalizer_light=False,
                            contains_weakptr=False):
     if (has_finalizer or
         (raw_malloc_usage(size) > self.lb_young_fixedsize and
          raw_malloc_usage(size) > self.largest_young_fixedsize)):
         # ^^^ we do two size comparisons; the first one appears redundant,
         #     but it can be constant-folded if 'size' is a constant; then
         #     it almost always folds down to False, which kills the
         #     second comparison as well.
         ll_assert(not contains_weakptr, "wrong case for mallocing weakref")
         # "non-simple" case or object too big: don't use the nursery
         return SemiSpaceGC.malloc_fixedsize_clear(self, typeid, size,
                                                   has_finalizer,
                                                   is_finalizer_light,
                                                   contains_weakptr)
     size_gc_header = self.gcheaderbuilder.size_gc_header
     totalsize = size_gc_header + size
     result = self.nursery_free
     if raw_malloc_usage(totalsize) > self.nursery_top - result:
         result = self.collect_nursery()
     llarena.arena_reserve(result, totalsize)
     # GCFLAG_NO_YOUNG_PTRS is never set on young objs
     self.init_gc_object(result, typeid, flags=0)
     self.nursery_free = result + totalsize
     if contains_weakptr:
         self.young_objects_with_weakrefs.append(result + size_gc_header)
     return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
Beispiel #6
0
 def malloc_fixedsize_clear(self, typeid, size,
                            has_finalizer=False,
                            is_finalizer_light=False,
                            contains_weakptr=False):
     if (has_finalizer or
         (raw_malloc_usage(size) > self.lb_young_fixedsize and
          raw_malloc_usage(size) > self.largest_young_fixedsize)):
         # ^^^ we do two size comparisons; the first one appears redundant,
         #     but it can be constant-folded if 'size' is a constant; then
         #     it almost always folds down to False, which kills the
         #     second comparison as well.
         ll_assert(not contains_weakptr, "wrong case for mallocing weakref")
         # "non-simple" case or object too big: don't use the nursery
         return SemiSpaceGC.malloc_fixedsize_clear(self, typeid, size,
                                                   has_finalizer,
                                                   is_finalizer_light,
                                                   contains_weakptr)
     size_gc_header = self.gcheaderbuilder.size_gc_header
     totalsize = size_gc_header + size
     result = self.nursery_free
     if raw_malloc_usage(totalsize) > self.nursery_top - result:
         result = self.collect_nursery()
     llarena.arena_reserve(result, totalsize)
     # GCFLAG_NO_YOUNG_PTRS is never set on young objs
     self.init_gc_object(result, typeid, flags=0)
     self.nursery_free = result + totalsize
     if contains_weakptr:
         self.young_objects_with_weakrefs.append(result + size_gc_header)
     return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
Beispiel #7
0
 def _compute_id(self, obj):
     if self.is_in_nursery(obj):
         result = self.young_objects_with_id.get(obj)
         if not result:
             result = self._next_id()
             self.young_objects_with_id.setitem(obj, result)
         return result
     else:
         return SemiSpaceGC._compute_id(self, obj)
Beispiel #8
0
 def _compute_id(self, obj):
     if self.is_in_nursery(obj):
         result = self.young_objects_with_id.get(obj)
         if not result:
             result = self._next_id()
             self.young_objects_with_id.setitem(obj, result)
         return result
     else:
         return SemiSpaceGC._compute_id(self, obj)
Beispiel #9
0
 def debug_check_object(self, obj):
     """Check the invariants about 'obj' that should be true
     between collections."""
     SemiSpaceGC.debug_check_object(self, obj)
     tid = self.header(obj).tid
     if tid & GCFLAG_NO_YOUNG_PTRS:
         ll_assert(not self.is_in_nursery(obj),
                   "nursery object with GCFLAG_NO_YOUNG_PTRS")
         self.trace(obj, self._debug_no_nursery_pointer, None)
     elif not self.is_in_nursery(obj):
         ll_assert(self._d_oopty.contains(obj),
                   "missing from old_objects_pointing_to_young")
     if tid & GCFLAG_NO_HEAP_PTRS:
         ll_assert(self.is_last_generation(obj),
                   "GCFLAG_NO_HEAP_PTRS on non-3rd-generation object")
         self.trace(obj, self._debug_no_gen1or2_pointer, None)
     elif self.is_last_generation(obj):
         ll_assert(self._d_lgro.contains(obj),
                   "missing from last_generation_root_objects")
Beispiel #10
0
 def debug_check_object(self, obj):
     """Check the invariants about 'obj' that should be true
     between collections."""
     SemiSpaceGC.debug_check_object(self, obj)
     tid = self.header(obj).tid
     if tid & GCFLAG_NO_YOUNG_PTRS:
         ll_assert(not self.is_in_nursery(obj),
                   "nursery object with GCFLAG_NO_YOUNG_PTRS")
         self.trace(obj, self._debug_no_nursery_pointer, None)
     elif not self.is_in_nursery(obj):
         ll_assert(self._d_oopty.contains(obj),
                   "missing from old_objects_pointing_to_young")
     if tid & GCFLAG_NO_HEAP_PTRS:
         ll_assert(self.is_last_generation(obj),
                   "GCFLAG_NO_HEAP_PTRS on non-3rd-generation object")
         self.trace(obj, self._debug_no_gen1or2_pointer, None)
     elif self.is_last_generation(obj):
         ll_assert(self._d_lgro.contains(obj),
                   "missing from last_generation_root_objects")
Beispiel #11
0
    def setup(self):
        self.old_objects_pointing_to_young = self.AddressStack()
        # ^^^ a list of addresses inside the old objects space; it
        # may contain static prebuilt objects as well.  More precisely,
        # it lists exactly the old and static objects whose
        # GCFLAG_NO_YOUNG_PTRS bit is not set.
        self.young_objects_with_weakrefs = self.AddressStack()

        self.last_generation_root_objects = self.AddressStack()
        self.young_objects_with_id = self.AddressDict()
        SemiSpaceGC.setup(self)
        self.set_nursery_size(self.initial_nursery_size)
        # the GC is fully setup now.  The rest can make use of it.
        if self.auto_nursery_size:
            newsize = nursery_size_from_env()
            #if newsize <= 0:
            #    ---disabled--- just use the default value.
            #    newsize = env.estimate_best_nursery_size()
            if newsize > 0:
                self.set_nursery_size(newsize)

        self.reset_nursery()
Beispiel #12
0
    def setup(self):
        self.old_objects_pointing_to_young = self.AddressStack()
        # ^^^ a list of addresses inside the old objects space; it
        # may contain static prebuilt objects as well.  More precisely,
        # it lists exactly the old and static objects whose
        # GCFLAG_NO_YOUNG_PTRS bit is not set.
        self.young_objects_with_weakrefs = self.AddressStack()

        self.last_generation_root_objects = self.AddressStack()
        self.young_objects_with_id = self.AddressDict()
        SemiSpaceGC.setup(self)
        self.set_nursery_size(self.initial_nursery_size)
        # the GC is fully setup now.  The rest can make use of it.
        if self.auto_nursery_size:
            newsize = nursery_size_from_env()
            #if newsize <= 0:
            #    ---disabled--- just use the default value.
            #    newsize = env.estimate_best_nursery_size()
            if newsize > 0:
                self.set_nursery_size(newsize)

        self.reset_nursery()
Beispiel #13
0
    def malloc_varsize_clear(self, typeid, length, size, itemsize,
                             offset_to_length):
        # Only use the nursery if there are not too many items.
        if not raw_malloc_usage(itemsize):
            too_many_items = False
        else:
            # The following line is usually constant-folded because both
            # min_nursery_size and itemsize are constants (the latter
            # due to inlining).
            maxlength_for_minimal_nursery = (self.min_nursery_size // 4 //
                                             raw_malloc_usage(itemsize))

            # The actual maximum length for our nursery depends on how
            # many times our nursery is bigger than the minimal size.
            # The computation is done in this roundabout way so that
            # only the only remaining computation is the following
            # shift.
            maxlength = maxlength_for_minimal_nursery << self.nursery_scale
            too_many_items = length > maxlength

        if (too_many_items or
            (raw_malloc_usage(size) > self.lb_young_var_basesize
             and raw_malloc_usage(size) > self.largest_young_var_basesize)):
            # ^^^ we do two size comparisons; the first one appears redundant,
            #     but it can be constant-folded if 'size' is a constant; then
            #     it almost always folds down to False, which kills the
            #     second comparison as well.
            return SemiSpaceGC.malloc_varsize_clear(self, typeid, length, size,
                                                    itemsize, offset_to_length)
        # with the above checks we know now that totalsize cannot be more
        # than about half of the nursery size; in particular, the + and *
        # cannot overflow
        size_gc_header = self.gcheaderbuilder.size_gc_header
        totalsize = size_gc_header + size + itemsize * length
        result = self.nursery_free
        if raw_malloc_usage(totalsize) > self.nursery_top - result:
            result = self.collect_nursery()
        llarena.arena_reserve(result, totalsize)
        # GCFLAG_NO_YOUNG_PTRS is never set on young objs
        self.init_gc_object(result, typeid, flags=0)
        (result + size_gc_header + offset_to_length).signed[0] = length
        self.nursery_free = result + llarena.round_up_for_allocation(totalsize)
        return llmemory.cast_adr_to_ptr(result + size_gc_header,
                                        llmemory.GCREF)
Beispiel #14
0
    def malloc_varsize_clear(self, typeid, length, size, itemsize,
                             offset_to_length):
        # Only use the nursery if there are not too many items.
        if not raw_malloc_usage(itemsize):
            too_many_items = False
        else:
            # The following line is usually constant-folded because both
            # min_nursery_size and itemsize are constants (the latter
            # due to inlining).
            maxlength_for_minimal_nursery = (self.min_nursery_size // 4 //
                                             raw_malloc_usage(itemsize))
            
            # The actual maximum length for our nursery depends on how
            # many times our nursery is bigger than the minimal size.
            # The computation is done in this roundabout way so that
            # only the only remaining computation is the following
            # shift.
            maxlength = maxlength_for_minimal_nursery << self.nursery_scale
            too_many_items = length > maxlength

        if (too_many_items or
            (raw_malloc_usage(size) > self.lb_young_var_basesize and
             raw_malloc_usage(size) > self.largest_young_var_basesize)):
            # ^^^ we do two size comparisons; the first one appears redundant,
            #     but it can be constant-folded if 'size' is a constant; then
            #     it almost always folds down to False, which kills the
            #     second comparison as well.
            return SemiSpaceGC.malloc_varsize_clear(self, typeid, length, size,
                                                    itemsize, offset_to_length)
        # with the above checks we know now that totalsize cannot be more
        # than about half of the nursery size; in particular, the + and *
        # cannot overflow
        size_gc_header = self.gcheaderbuilder.size_gc_header
        totalsize = size_gc_header + size + itemsize * length
        result = self.nursery_free
        if raw_malloc_usage(totalsize) > self.nursery_top - result:
            result = self.collect_nursery()
        llarena.arena_reserve(result, totalsize)
        # GCFLAG_NO_YOUNG_PTRS is never set on young objs
        self.init_gc_object(result, typeid, flags=0)
        (result + size_gc_header + offset_to_length).signed[0] = length
        self.nursery_free = result + llarena.round_up_for_allocation(totalsize)
        return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
Beispiel #15
0
 def _teardown(self):
     self.collect() # should restore last gen objects flags
     SemiSpaceGC._teardown(self)
Beispiel #16
0
 def debug_check_can_copy(self, obj):
     if self.is_in_nursery(obj):
         pass    # it's ok to copy an object out of the nursery
     else:
         SemiSpaceGC.debug_check_can_copy(self, obj)
Beispiel #17
0
 def init_gc_object(self, addr, typeid, flags=GCFLAG_NO_YOUNG_PTRS):
     SemiSpaceGC.init_gc_object(self, addr, typeid, flags)
Beispiel #18
0
 def init_gc_object_immortal(self, addr, typeid,
                             flags=GCFLAG_NO_YOUNG_PTRS|GCFLAG_NO_HEAP_PTRS):
     SemiSpaceGC.init_gc_object_immortal(self, addr, typeid, flags)
Beispiel #19
0
 def enumerate_all_roots(self, callback, arg):
     self.last_generation_root_objects.foreach(callback, arg)
     SemiSpaceGC.enumerate_all_roots(self, callback, arg)
Beispiel #20
0
 def collect(self, gen=1):
     if gen == 0:
         self.collect_nursery()
     else:
         SemiSpaceGC.collect(self)
Beispiel #21
0
 def semispace_collect(self, size_changing=False):
     self.reset_young_gcflags() # we are doing a full collection anyway
     self.weakrefs_grow_older()
     self.ids_grow_older()
     self.reset_nursery()
     SemiSpaceGC.semispace_collect(self, size_changing)
Beispiel #22
0
 def semispace_collect(self, size_changing=False):
     self.reset_young_gcflags() # we are doing a full collection anyway
     self.weakrefs_grow_older()
     self.ids_grow_older()
     self.reset_nursery()
     SemiSpaceGC.semispace_collect(self, size_changing)
Beispiel #23
0
 def collect(self, gen=1):
     if gen == 0:
         self.collect_nursery()
     else:
         SemiSpaceGC.collect(self)
Beispiel #24
0
 def init_gc_object_immortal(self, addr, typeid,
                             flags=GCFLAG_NO_YOUNG_PTRS|GCFLAG_NO_HEAP_PTRS):
     SemiSpaceGC.init_gc_object_immortal(self, addr, typeid, flags)
Beispiel #25
0
 def init_gc_object(self, addr, typeid, flags=GCFLAG_NO_YOUNG_PTRS):
     SemiSpaceGC.init_gc_object(self, addr, typeid, flags)
Beispiel #26
0
 def enumerate_all_roots(self, callback, arg):
     self.last_generation_root_objects.foreach(callback, arg)
     SemiSpaceGC.enumerate_all_roots(self, callback, arg)
Beispiel #27
0
 def _teardown(self):
     self.collect() # should restore last gen objects flags
     SemiSpaceGC._teardown(self)
Beispiel #28
0
 def debug_check_can_copy(self, obj):
     if self.is_in_nursery(obj):
         pass    # it's ok to copy an object out of the nursery
     else:
         SemiSpaceGC.debug_check_can_copy(self, obj)