Пример #1
0
 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
Пример #2
0
 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)
Пример #3
0
 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
Пример #4
0
 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)