def identityhash(self, gcobj): # The following code should run at most twice. while 1: obj = llmemory.cast_ptr_to_adr(gcobj) hdr = self.header(obj) # if hdr.tid & GCFLAG_HASHFIELD: # the hash is in a field at the end obj += self.get_size(obj) return obj.signed[0] # if not (hdr.tid & GCFLAG_HASHTAKEN): # It's the first time we ask for a hash, and it's not an # external object. Shrink the top of space by the extra # hash word that will be needed after a collect. shrunk_top = self.top_of_space - llmemory.sizeof(lltype.Signed) if shrunk_top < self.free: # Cannot shrink! Do a collection, asking for at least # one word of free space, and try again. May raise # MemoryError. Obscure: not called directly, but # across an llop, to make sure that there is the # correct push_roots/pop_roots around the call... llop.gc_obtain_free_space(llmemory.Address, llmemory.sizeof(lltype.Signed)) continue # Now we can have side-effects: set GCFLAG_HASHTAKEN # and lower the top of space. self.top_of_space = shrunk_top hdr.tid |= GCFLAG_HASHTAKEN # return llmemory.cast_adr_to_int(obj) # direct case
def identityhash(self, gcobj): # The following loop should run at most twice. while 1: obj = llmemory.cast_ptr_to_adr(gcobj) hdr = self.header(obj) if hdr.tid & GCFLAG_HASHMASK: break # It's the first time we ask for a hash, and it's not an # external object. Shrink the top of space by the extra # hash word that will be needed after a collect. shrunk_top = self.top_of_space - llmemory.sizeof(lltype.Signed) if shrunk_top < self.free: # Cannot shrink! Do a collection, asking for at least # one word of free space, and try again. May raise # MemoryError. Obscure: not called directly, but # across an llop, to make sure that there is the # correct push_roots/pop_roots around the call... llop.gc_obtain_free_space(llmemory.Address, llmemory.sizeof(lltype.Signed)) continue else: # Now we can have side-effects: lower the top of space # and set one of the GC_HASH_TAKEN_xxx flags. self.top_of_space = shrunk_top if self.is_in_nursery(obj): hdr.tid |= GC_HASH_TAKEN_NURS else: hdr.tid |= GC_HASH_TAKEN_ADDR break # Now we can return the result objsize = self.get_size(obj) return self._get_object_hash(obj, objsize, hdr.tid)
def identityhash(self, gcobj): # The following code should run at most twice. while 1: obj = llmemory.cast_ptr_to_adr(gcobj) hdr = self.header(obj) # if hdr.tid & GCFLAG_HASHFIELD: # the hash is in a field at the end obj += self.get_size(obj) return obj.signed[0] # if not (hdr.tid & GCFLAG_HASHTAKEN): # It's the first time we ask for a hash, and it's not an # external object. Shrink the top of space by the extra # hash word that will be needed after a collect. shrunk_top = self.top_of_space - llmemory.sizeof(lltype.Signed) if shrunk_top < self.free: # Cannot shrink! Do a collection, asking for at least # one word of free space, and try again. May raise # MemoryError. Obscure: not called directly, but # across an llop, to make sure that there is the # correct push_roots/pop_roots around the call... llop.gc_obtain_free_space(llmemory.Address, llmemory.sizeof(lltype.Signed)) continue # Now we can have side-effects: set GCFLAG_HASHTAKEN # and lower the top of space. self.top_of_space = shrunk_top hdr.tid |= GCFLAG_HASHTAKEN # return llmemory.cast_adr_to_int(obj) # direct case
def identityhash(self, gcobj): # The following loop should run at most twice. while 1: obj = llmemory.cast_ptr_to_adr(gcobj) hdr = self.header(obj) if hdr.tid & GCFLAG_HASHMASK: break # It's the first time we ask for a hash, and it's not an # external object. Shrink the top of space by the extra # hash word that will be needed after a collect. shrunk_top = self.top_of_space - llmemory.sizeof(lltype.Signed) if shrunk_top < self.free: # Cannot shrink! Do a collection, asking for at least # one word of free space, and try again. May raise # MemoryError. Obscure: not called directly, but # across an llop, to make sure that there is the # correct push_roots/pop_roots around the call... llop.gc_obtain_free_space(llmemory.Address, llmemory.sizeof(lltype.Signed)) continue else: # Now we can have side-effects: lower the top of space # and set one of the GC_HASH_TAKEN_xxx flags. self.top_of_space = shrunk_top if self.is_in_nursery(obj): hdr.tid |= GC_HASH_TAKEN_NURS else: hdr.tid |= GC_HASH_TAKEN_ADDR break # Now we can return the result objsize = self.get_size(obj) return self._get_object_hash(obj, objsize, hdr.tid)