def get_instances_array_gc(interp, w_class=None): space = interp.space from rpython.rlib import rgc result_w = [] roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = rgc.try_cast_gcref_to_instance(W_Object, gcref) if w_obj is not None and w_obj.has_class(): w_cls = w_obj.getclass(space) if w_cls is not None: # XXX: should not return SmallFloat64 on Spur64... if ((not w_cls.is_same_object(space.w_SmallInteger)) and (not (space.is_spur.is_set() and w_cls.is_same_object(space.w_Character))) and (w_class is None or w_cls.is_same_object(w_class))): result_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) rgc.clear_gcflag_extra(roots) rgc.assert_no_more_gcflags() return result_w
def _list_w_obj_referents(gcref, result_w): # Get all W_Root reachable directly from gcref, and add them to # the list 'result_w'. pending = [] # = list of all objects whose gcflag was toggled i = 0 gcrefparent = gcref while True: for gcref in rgc.get_rpy_referents(gcrefparent): if rgc.get_gcflag_extra(gcref): continue rgc.toggle_gcflag_extra(gcref) pending.append(gcref) while i < len(pending): gcrefparent = pending[i] i += 1 w_obj = try_cast_gcref_to_w_root(gcrefparent) if w_obj is not None: result_w.append(w_obj) else: break # jump back to the start of the outermost loop else: break # done for gcref in pending: rgc.toggle_gcflag_extra(gcref) # reset the gcflag_extra's
def clear_gcflag_extra(fromlist): pending = fromlist[:] while pending: gcref = pending.pop() if rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) pending.extend(rgc.get_rpy_referents(gcref))
def do_get_objects(): roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] result_w = [] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = try_cast_gcref_to_w_root(gcref) if w_obj is not None: result_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) clear_gcflag_extra(roots) return result_w
def method_each_object(self, space, w_mod, block): match_w = [] roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = try_cast_gcref_to_w_baseobject(gcref) if w_obj is not None and space.is_kind_of(w_obj, w_mod): match_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) clear_gcflag_extra(roots) for w_obj in match_w: space.invoke_block(block, [w_obj])
def getMonteObjects(): roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] result_w = [] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = rgc.try_cast_gcref_to_instance(Object, gcref) if w_obj is not None: result_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) clear_gcflag_extra(roots) rgc.assert_no_more_gcflags() return result_w
def method_each_object(self, space, w_mod, block): if block is None: return space.send(self, "enum_for", [space.newsymbol("each_object"), w_mod], block) match_w = [] roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = try_cast_gcref_to_w_baseobject(gcref) if w_obj is not None and space.is_kind_of(w_obj, w_mod): match_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) clear_gcflag_extra(roots) for w_obj in match_w: space.invoke_block(block, [w_obj]) return space.newint(len(match_w))
def do_get_referrers(w_arg): result_w = [] gcarg = rgc.cast_instance_to_gcref(w_arg) roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] head = PathEntry(None, rgc.NULL_GCREF, roots) while True: head.remaining -= 1 if head.remaining >= 0: gcref = head.referents[head.remaining] if not rgc.get_gcflag_extra(gcref): # not visited so far if gcref == gcarg: w_obj = head.get_most_recent_w_obj() if w_obj is not None: result_w.append(w_obj) # found! rgc.toggle_gcflag_extra(gcref) # toggle twice rgc.toggle_gcflag_extra(gcref) head = PathEntry(head, gcref, rgc.get_rpy_referents(gcref)) else: # no more referents to visit head = head.prev if head is None: break # done. Clear flags carefully rgc.toggle_gcflag_extra(gcarg) clear_gcflag_extra(roots) clear_gcflag_extra([gcarg]) return result_w
def do_get_referrers(w_arg): result_w = [] gcarg = rgc.cast_instance_to_gcref(w_arg) roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] head = PathEntry(None, rgc.NULL_GCREF, roots) while True: head.remaining -= 1 if head.remaining >= 0: gcref = head.referents[head.remaining] if not rgc.get_gcflag_extra(gcref): # not visited so far if gcref == gcarg: w_obj = head.get_most_recent_w_obj() if w_obj is not None: result_w.append(w_obj) # found! rgc.toggle_gcflag_extra(gcref) # toggle twice rgc.toggle_gcflag_extra(gcref) head = PathEntry(head, gcref, rgc.get_rpy_referents(gcref)) else: # no more referents to visit head = head.prev if head is None: break # done. Clear flags carefully rgc.toggle_gcflag_extra(gcarg) rgc.clear_gcflag_extra(roots) rgc.clear_gcflag_extra([gcarg]) return result_w
def fn(): a2 = A() if not rgc.has_gcflag_extra(): return # cannot test it then assert rgc.get_gcflag_extra(a1) == False assert rgc.get_gcflag_extra(a2) == False rgc.toggle_gcflag_extra(a1) assert rgc.get_gcflag_extra(a1) == True assert rgc.get_gcflag_extra(a2) == False rgc.toggle_gcflag_extra(a2) assert rgc.get_gcflag_extra(a1) == True assert rgc.get_gcflag_extra(a2) == True rgc.toggle_gcflag_extra(a1) assert rgc.get_gcflag_extra(a1) == False assert rgc.get_gcflag_extra(a2) == True rgc.toggle_gcflag_extra(a2) assert rgc.get_gcflag_extra(a1) == False assert rgc.get_gcflag_extra(a2) == False
def clear_gcflag_extra(pending): while pending: gcref = pending.pop() if rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) pending.extend(rgc.get_rpy_referents(gcref))