def ll_keyeq(d, weakkey1, realkey2): # only called by ll_dict_lookup() with the first arg coming from an # entry.key, and the 2nd arg being the argument to ll_dict_lookup(). if not weakkey1: assert bool(realkey2) return False return weakref_deref(rclass.OBJECTPTR, weakkey1) == realkey2
def ll_get(d, llkey): hash = ll_strhash(llkey) i = rdict.ll_dict_lookup(d, llkey, hash) #llop.debug_print(lltype.Void, i, 'get') valueref = d.entries[i].value if valueref: return weakref_deref(rclass.OBJECTPTR, valueref) else: return lltype.nullptr(rclass.OBJECTPTR.TO)
def ll_valid(entries, i): key = entries[i].key if not key: return False elif weakref_deref(rclass.OBJECTPTR, key): return True else: # The entry might be a dead weakref still holding a strong # reference to the value; for this case, we clear the old # value from the entry, if any. entries[i].value = NULLVALUE return False
def _compute_id(self, ptr): # XXX this may explode if --no-translation-rweakref is specified # ---------------------------------------------------------------- # Basic logic: the list item wr_to_objects_with_id[i] contains a # weakref to the object whose id is i + 1. The object_id_dict is # an optimization that tries to reduce the number of linear # searches in this list. # ---------------------------------------------------------------- # Invariant: if object_id_dict_ends_at >= 0, then object_id_dict # contains all pairs {address: id}, for the addresses # of all objects that are the targets of the weakrefs of the # following slice: wr_to_objects_with_id[:object_id_dict_ends_at]. # ---------------------------------------------------------------- # Essential: as long as notify_objects_just_moved() is not called, # we assume that the objects' addresses did not change. We also # assume that the address of a live object cannot be reused for # another object without an intervening notify_objects_just_moved() # call, but this could be fixed easily if needed. # ---------------------------------------------------------------- # First check the dictionary i = self.object_id_dict_ends_at if i < 0: self.object_id_dict.clear() # dictionary invalid self.object_id_dict_ends_at = 0 i = 0 else: adr = llmemory.cast_ptr_to_adr(ptr) try: i = self.object_id_dict[adr] except KeyError: pass else: # double-check that the answer we got is correct lst = self.wr_to_objects_with_id target = llmemory.weakref_deref(llmemory.GCREF, lst[i]) ll_assert(target == ptr, "bogus object_id_dict") return i + 1 # found via the dict # Walk the tail of the list, where entries are not also in the dict lst = self.wr_to_objects_with_id end = len(lst) freeentry = -1 while i < end: target = llmemory.weakref_deref(llmemory.GCREF, lst[i]) if not target: freeentry = i else: ll_assert( self.get_type_id(llmemory.cast_ptr_to_adr(target)) > 0, "bogus weakref in compute_id()") # record this entry in the dict adr = llmemory.cast_ptr_to_adr(target) self.object_id_dict[adr] = i if target == ptr: break # found i += 1 else: # not found wr = llmemory.weakref_create(ptr) if freeentry < 0: ll_assert(end == len(lst), "unexpected lst growth in gc_id") i = end lst.append(wr) else: i = freeentry # reuse the id() of a dead object lst[i] = wr adr = llmemory.cast_ptr_to_adr(ptr) self.object_id_dict[adr] = i # all entries up to and including index 'i' are now valid in the dict # unless a collection occurred while we were working, in which case # the object_id_dict is bogus anyway if self.object_id_dict_ends_at >= 0: self.object_id_dict_ends_at = i + 1 return i + 1 # this produces id() values 1, 2, 3, 4...
def ll_valid(entries, i): return (bool(entries[i].value) and bool(weakref_deref(rclass.OBJECTPTR, entries[i].value)))
def ll_valid(entries, i): value = entries[i].value return bool(value) and bool(weakref_deref(rclass.OBJECTPTR, value))
def _compute_id(self, ptr): # XXX this may explode if --no-translation-rweakref is specified # ---------------------------------------------------------------- # Basic logic: the list item wr_to_objects_with_id[i] contains a # weakref to the object whose id is i + 1. The object_id_dict is # an optimization that tries to reduce the number of linear # searches in this list. # ---------------------------------------------------------------- # Invariant: if object_id_dict_ends_at >= 0, then object_id_dict # contains all pairs {address: id}, for the addresses # of all objects that are the targets of the weakrefs of the # following slice: wr_to_objects_with_id[:object_id_dict_ends_at]. # ---------------------------------------------------------------- # Essential: as long as notify_objects_just_moved() is not called, # we assume that the objects' addresses did not change. We also # assume that the address of a live object cannot be reused for # another object without an intervening notify_objects_just_moved() # call, but this could be fixed easily if needed. # ---------------------------------------------------------------- # First check the dictionary i = self.object_id_dict_ends_at if i < 0: self.object_id_dict.clear() # dictionary invalid self.object_id_dict_ends_at = 0 i = 0 else: adr = llmemory.cast_ptr_to_adr(ptr) try: i = self.object_id_dict[adr] except KeyError: pass else: # double-check that the answer we got is correct lst = self.wr_to_objects_with_id target = llmemory.weakref_deref(llmemory.GCREF, lst[i]) ll_assert(target == ptr, "bogus object_id_dict") return i + 1 # found via the dict # Walk the tail of the list, where entries are not also in the dict lst = self.wr_to_objects_with_id end = len(lst) freeentry = -1 while i < end: target = llmemory.weakref_deref(llmemory.GCREF, lst[i]) if not target: freeentry = i else: ll_assert(self.get_type_id(llmemory.cast_ptr_to_adr(target)) > 0, "bogus weakref in compute_id()") # record this entry in the dict adr = llmemory.cast_ptr_to_adr(target) self.object_id_dict[adr] = i if target == ptr: break # found i += 1 else: # not found wr = llmemory.weakref_create(ptr) if freeentry < 0: ll_assert(end == len(lst), "unexpected lst growth in gc_id") i = end lst.append(wr) else: i = freeentry # reuse the id() of a dead object lst[i] = wr adr = llmemory.cast_ptr_to_adr(ptr) self.object_id_dict[adr] = i # all entries up to and including index 'i' are now valid in the dict # unless a collection occurred while we were working, in which case # the object_id_dict is bogus anyway if self.object_id_dict_ends_at >= 0: self.object_id_dict_ends_at = i + 1 return i + 1 # this produces id() values 1, 2, 3, 4...
def f(): w = g() rgc.collect() return llmemory.weakref_deref(lltype.Ptr(S), w)
def g(): s = lltype.malloc(S) w = llmemory.weakref_create(s) assert llmemory.weakref_deref(lltype.Ptr(S), w) == s assert llmemory.weakref_deref(lltype.Ptr(S), w) == s return w # 's' is forgotten here