[pypy-svn] r68397 - in pypy/branch/gc-hash/pypy: rpython/memory/gc rpython/memory/gctransform translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Tue Oct 13 21:38:25 CEST 2009
Author: arigo
Date: Tue Oct 13 21:38:23 2009
New Revision: 68397
Modified:
pypy/branch/gc-hash/pypy/rpython/memory/gc/marksweep.py
pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py
pypy/branch/gc-hash/pypy/rpython/memory/gctransform/framework.py
pypy/branch/gc-hash/pypy/translator/c/test/test_newgc.py
Log:
Test passes with the semispace GC after collections
that move data around.
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gc/marksweep.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gc/marksweep.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gc/marksweep.py Tue Oct 13 21:38:23 2009
@@ -707,9 +707,7 @@
def identityhash(self, obj):
obj = llmemory.cast_ptr_to_adr(obj)
- size_gc_header = self.gcheaderbuilder.size_gc_header
- gc_info = obj - size_gc_header
- hdr = llmemory.cast_adr_to_ptr(gc_info, self.HDRPTR)
+ hdr = self.header(obj)
if ord(hdr.flags) & FL_WITHHASH:
obj += self.get_size(obj)
return obj.signed[0]
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py Tue Oct 13 21:38:23 2009
@@ -19,6 +19,8 @@
# either immortal objects or (for HybridGC) externally raw_malloc'ed
GCFLAG_EXTERNAL = first_gcflag << 1
GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2
+GCFLAG_HASHTAKEN = first_gcflag << 3 # someone already asked for the hash
+GCFLAG_HASHFIELD = first_gcflag << 4 # we have an extra hash field
memoryError = MemoryError()
@@ -28,12 +30,13 @@
inline_simple_malloc = True
inline_simple_malloc_varsize = True
malloc_zero_filled = True
- first_unused_gcflag = first_gcflag << 3
+ first_unused_gcflag = first_gcflag << 5
total_collection_time = 0.0
total_collection_count = 0
HDR = lltype.Struct('header', ('tid', lltype.Signed)) # XXX or rffi.INT?
typeid_is_in_field = 'tid'
+ withhash_flag_is_in_field = 'tid', (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD)
FORWARDSTUB = lltype.GcStruct('forwarding_stub',
('forw', llmemory.Address))
FORWARDSTUBPTR = lltype.Ptr(FORWARDSTUB)
@@ -297,11 +300,19 @@
if free_after_collection < self.space_size // 5:
self.red_zone += 1
+ def extra_hash_space(self, obj):
+ hdr = self.header(obj)
+ if hdr.tid & GCFLAG_HASHFIELD:
+ return llmemory.sizeof(lltype.Signed)
+ else:
+ return 0
+
def scan_copied(self, scan):
while scan < self.free:
curr = scan + self.size_gc_header()
self.trace_and_copy(curr)
- scan += self.size_gc_header() + self.get_size(curr)
+ scan += (self.size_gc_header() + self.get_size(curr)
+ + self.extra_hash_space(curr))
return scan
def collect_roots(self):
@@ -331,9 +342,21 @@
def make_a_copy(self, obj, objsize):
totalsize = self.size_gc_header() + objsize
newaddr = self.free
- self.free += totalsize
llarena.arena_reserve(newaddr, totalsize)
raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize)
+ #
+ # check if we need to write a hash value at the end of the new obj
+ newhdr = llmemory.cast_adr_to_ptr(newaddr, lltype.Ptr(self.HDR))
+ if newhdr.tid & (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD):
+ if newhdr.tid & GCFLAG_HASHFIELD:
+ hash = (obj + self.get_size(obj)).signed[0]
+ else:
+ hash = llmemory.cast_adr_to_int(obj)
+ newhdr.tid |= GCFLAG_HASHFIELD
+ (newaddr + totalsize).signed[0] = hash
+ totalsize += llmemory.sizeof(lltype.Signed)
+ #
+ self.free += totalsize
newobj = newaddr + self.size_gc_header()
return newobj
@@ -570,3 +593,12 @@
STATISTICS_NUMBERS = 0
+ def identityhash(self, obj):
+ obj = llmemory.cast_ptr_to_adr(obj)
+ hdr = self.header(obj)
+ if hdr.tid & GCFLAG_HASHFIELD:
+ obj += self.get_size(obj)
+ return obj.signed[0]
+ else:
+ hdr.tid |= GCFLAG_HASHTAKEN
+ return llmemory.cast_adr_to_int(obj)
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gctransform/framework.py Tue Oct 13 21:38:23 2009
@@ -439,7 +439,7 @@
def gc_field_values_for(self, obj):
hdr = self.gcdata.gc.gcheaderbuilder.header_of_object(obj)
HDR = self._gc_HDR
- withhash, flag = self.gcdata.gc.withhash_flag_is_in_field
+ withhash, flags = self.gcdata.gc.withhash_flag_is_in_field
result = []
for fldname in HDR._names:
x = getattr(hdr, fldname)
@@ -447,9 +447,9 @@
TYPE = lltype.typeOf(x)
x = lltype.cast_primitive(lltype.Signed, x)
if hasattr(obj._normalizedcontainer(), '_hash_cache_'):
- x |= flag
+ x |= flags # set the flag(s) in the header
else:
- x &= ~flag
+ x &= ~flags # clear the flag(s) in the header
x = lltype.cast_primitive(TYPE, x)
result.append(x)
return result
Modified: pypy/branch/gc-hash/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/gc-hash/pypy/translator/c/test/test_newgc.py (original)
+++ pypy/branch/gc-hash/pypy/translator/c/test/test_newgc.py Tue Oct 13 21:38:23 2009
@@ -702,11 +702,17 @@
h_t = compute_hash(("Hi", None, (7.5, 2, d)))
#
def f():
- d2 = D()
- if compute_hash(d2) != current_object_addr_as_int(d2): return 11
if compute_hash(c) != compute_hash(c): return 12
if compute_hash(d) != h_d: return 13
if compute_hash(("Hi", None, (7.5, 2, d))) != h_t: return 14
+ c2 = C()
+ h_c2 = compute_hash(c2)
+ if compute_hash(c2) != h_c2: return 15
+ i = 0
+ while i < 6:
+ rgc.collect()
+ if compute_hash(c2) != h_c2: return i
+ i += 1
return 42
return f
More information about the Pypy-commit
mailing list