def ll_set_nonnull(d, llkey, llvalue): hash = ll_strhash(llkey) valueref = weakref_create(llvalue) # GC effects here, before the rest i = rdict.ll_dict_lookup(d, llkey, hash) everused = d.entries.everused(i) d.entries[i].key = llkey d.entries[i].value = valueref #llop.debug_print(lltype.Void, i, 'stored') if not everused: d.num_pristine_entries -= 1 if d.num_pristine_entries <= len(d.entries) / 3: #llop.debug_print(lltype.Void, 'RESIZE') ll_weakdict_resize(d)
def ll_set_nonnull(self, d, llkey, llvalue): hash = self.ll_keyhash(llkey) valueref = weakref_create(llvalue) # GC effects here, before the rest i = rdict.ll_dict_lookup(d, llkey, hash) & rdict.MASK everused = d.entries.everused(i) d.entries[i].key = llkey d.entries[i].value = valueref #llop.debug_print(lltype.Void, i, 'stored') if not everused: d.resize_counter -= 3 if d.resize_counter <= 0: #llop.debug_print(lltype.Void, 'RESIZE') self.ll_weakdict_resize(d)
def ll_set_nonnull(self, d, llkey, llvalue): hash = self.ll_keyhash(llkey) valueref = weakref_create(llvalue) # GC effects here, before the rest i = rdict.ll_dict_lookup(d, llkey, hash) & rdict.MASK everused = d.entries.everused(i) d.entries[i].key = llkey d.entries[i].value = valueref # llop.debug_print(lltype.Void, i, 'stored') if not everused: d.resize_counter -= 3 if d.resize_counter <= 0: # llop.debug_print(lltype.Void, 'RESIZE') self.ll_weakdict_resize(d)
def ll_set_nonnull(d, llkey, llvalue): hash = compute_identity_hash(llkey) keyref = weakref_create(llkey) # GC effects here, before the rest i = rdict.ll_dict_lookup(d, llkey, hash) & rdict.MASK everused = d.entries.everused(i) d.entries[i].key = keyref d.entries[i].value = llvalue d.entries[i].f_hash = hash #llop.debug_print(lltype.Void, i, 'stored', hex(hash), # ll_debugrepr(llkey), # ll_debugrepr(llvalue)) if not everused: d.resize_counter -= 3 if d.resize_counter <= 0: #llop.debug_print(lltype.Void, 'RESIZE') ll_weakdict_resize(d)
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 weakref_create_getlazy(objgetter): return weakref_create(objgetter())
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 _weakref_create(self, llinstance): return llmemory.weakref_create(llinstance)
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