[pypy-svn] r77572 - in pypy/branch/32ptr-on-64bit/pypy: annotation config rpython rpython/lltypesystem rpython/memory rpython/memory/gc rpython/memory/test rpython/test translator/c translator/c/src translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Mon Oct 4 15:30:25 CEST 2010
Author: arigo
Date: Mon Oct 4 15:30:22 2010
New Revision: 77572
Added:
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rcompressed.py
pypy/branch/32ptr-on-64bit/pypy/rpython/test/test_rcompressed.py
Modified:
pypy/branch/32ptr-on-64bit/pypy/annotation/model.py
pypy/branch/32ptr-on-64bit/pypy/config/translationoption.py
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/llmemory.py
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/opimpl.py
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rclass.py
pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rffi.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/base.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/minimark.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gctypelayout.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gcwrapper.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gc.py
pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gctypelayout.py
pypy/branch/32ptr-on-64bit/pypy/rpython/raddress.py
pypy/branch/32ptr-on-64bit/pypy/rpython/rmodel.py
pypy/branch/32ptr-on-64bit/pypy/translator/c/database.py
pypy/branch/32ptr-on-64bit/pypy/translator/c/node.py
pypy/branch/32ptr-on-64bit/pypy/translator/c/primitive.py
pypy/branch/32ptr-on-64bit/pypy/translator/c/src/commondefs.h
pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_lladdresses.py
pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_newgc.py
Log:
In-progress.
Modified: pypy/branch/32ptr-on-64bit/pypy/annotation/model.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/annotation/model.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/annotation/model.py Mon Oct 4 15:30:22 2010
@@ -518,6 +518,14 @@
def can_be_none(self):
return False
+# for compressed 32-bit "pointers" on 64-bit platforms
+
+class SomeHiddenGcRef32(SomeObject):
+ immutable = True
+
+ def can_be_none(self):
+ return False
+
#____________________________________________________________
# annotation of low-level types
@@ -582,6 +590,7 @@
(SomeChar(), lltype.Char),
(SomeUnicodeCodePoint(), lltype.UniChar),
(SomeAddress(), llmemory.Address),
+ (SomeHiddenGcRef32(), llmemory.HiddenGcRef32),
]
def annotation_to_lltype(s_val, info=None):
Modified: pypy/branch/32ptr-on-64bit/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/config/translationoption.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/config/translationoption.py Mon Oct 4 15:30:22 2010
@@ -193,6 +193,11 @@
"When true, enable the use of tagged pointers. "
"If false, use normal boxing",
default=False),
+ BoolOption("compressptr", "Compress pointers; limits the program to 32GB",
+ default=False, cmdline="--compressptr",
+ requires=[("translation.type_system", "lltype"),
+ ("translation.taggedpointers", False)]
+ + [("compressptr (64-bit only)", True)]*(not IS_64_BITS)),
# options for ootype
OptionDescription("ootype", "Object Oriented Typesystem options", [
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/llmemory.py Mon Oct 4 15:30:22 2010
@@ -8,6 +8,7 @@
from pypy.rlib.objectmodel import Symbolic
from pypy.rpython.lltypesystem import lltype
from pypy.tool.uid import uid
+from pypy.rlib.objectmodel import we_are_translated
class AddressOffset(Symbolic):
@@ -562,6 +563,61 @@
def array_item_type_match(T1, T2):
return T1 == T2 or (T2 == GCREF and isinstance(T1, lltype.Ptr))
+# ____________________________________________________________
+
+class _hiddengcref32(object):
+ """A 'hidden' compressed 32-bit value that represents a
+ full, 64-bit GC pointer."""
+
+ def __init__(self, adr64):
+ self.adr64 = adr64
+
+ def __repr__(self):
+ return '<_hiddengcref32>'
+
+ def __str__(self):
+ return '<_hiddengcref32 %s>' % (self.adr64,)
+
+compressed_null_addr = _hiddengcref32(NULL)
+HiddenGcRef32 = lltype.Primitive("HiddenGcRef32", compressed_null_addr)
+_hiddengcref32._TYPE = HiddenGcRef32
+
+class OddValueMarker(AddressOffset):
+ """This is the value '1'. Used as an odd-valued marker by the GC."""
+ def __repr__(self):
+ return '< OddValueMarker 1 >'
+ def ref(self, ptr):
+ raise AssertionError("should not try to directly get the address"
+ " from a HiddenGcRef32")
+
+def has_odd_value_marker(addressofs):
+ if we_are_translated():
+ return bool(addressofs & 1)
+ return _has_odd_value_marker(addressofs)
+
+def _has_odd_value_marker(addressofs):
+ while isinstance(addressofs, CompositeOffset):
+ addressofs = addressofs.offsets[-1]
+ return isinstance(addressofs, OddValueMarker)
+
+def remove_odd_value_marker(addressofs):
+ if we_are_translated():
+ return addressofs - 1
+ return _remove_odd_value_marker(addressofs)
+
+def _remove_odd_value_marker(addressofs):
+ if isinstance(addressofs, CompositeOffset):
+ offsets = list(addressofs.offsets)
+ offsets[-1] = _remove_odd_value_marker(offsets[-1])
+ if offsets[-1] == 0:
+ del offsets[-1]
+ if len(offsets) == 1:
+ return offsets[0]
+ return CompositeOffset(*offsets)
+ assert isinstance(addressofs, OddValueMarker)
+ return 0
+
+# ____________________________________________________________
class _fakeaccessor(object):
def __init__(self, addr):
@@ -597,6 +653,9 @@
class _char_fakeaccessor(_fakeaccessor):
TYPE = lltype.Char
+class _hiddengcref32_fakeaccessor(_fakeaccessor):
+ TYPE = HiddenGcRef32
+
class _address_fakeaccessor(_fakeaccessor):
TYPE = Address
@@ -624,12 +683,14 @@
"char": lltype.Char,
"address": Address,
"float": lltype.Float,
+ "hiddengcref32": HiddenGcRef32,
}
fakeaddress.signed = property(_signed_fakeaccessor)
fakeaddress.float = property(_float_fakeaccessor)
fakeaddress.char = property(_char_fakeaccessor)
fakeaddress.address = property(_address_fakeaccessor)
+fakeaddress.hiddengcref32 = property(_hiddengcref32_fakeaccessor)
fakeaddress._TYPE = Address
# the obtained address will not keep the object alive. e.g. if the object is
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/lloperation.py Mon Oct 4 15:30:22 2010
@@ -426,6 +426,9 @@
'gc_gettypeptr_group': LLOp(canfold=True),
'get_member_index': LLOp(canfold=True),
+ 'hide_into_adr32': LLOp(canrun=True),
+ 'show_from_adr32': LLOp(canrun=True),
+
# __________ used by the JIT ________
'jit_marker': LLOp(),
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/opimpl.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/opimpl.py Mon Oct 4 15:30:22 2010
@@ -526,6 +526,18 @@
def op_shrink_array(array, smallersize):
return False
+def op_hide_into_adr32(adr):
+ if lltype.typeOf(adr) != llmemory.Address:
+ adr = llmemory.cast_ptr_to_adr(adr)
+ return llmemory._hiddengcref32(adr)
+
+def op_show_from_adr32(RESTYPE, adr32):
+ if RESTYPE == llmemory.Address:
+ return adr32.adr64
+ else:
+ return llmemory.cast_adr_to_ptr(adr32.adr64, RESTYPE)
+op_show_from_adr32.need_result_type = True
+
# ____________________________________________________________
def get_op_impl(opname):
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rclass.py Mon Oct 4 15:30:22 2010
@@ -4,6 +4,7 @@
from pypy.objspace.flow.model import Constant
from pypy.rpython.error import TyperError
from pypy.rpython.rmodel import Repr, inputconst, warning, mangle
+from pypy.rpython.rmodel import externalvsinternalfield
from pypy.rpython.rclass import AbstractClassRepr,\
AbstractInstanceRepr,\
MissingRTypeAttribute,\
@@ -326,7 +327,8 @@
fields = {}
allinstancefields = {}
if self.classdef is None:
- fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
+ r = get_type_repr(self.rtyper)
+ fields['__class__'] = 'typeptr', r, r
else:
# instance attributes
if llfields is None:
@@ -337,8 +339,12 @@
if not attrdef.readonly:
r = self.rtyper.getrepr(attrdef.s_value)
mangled_name = 'inst_' + name
- fields[name] = mangled_name, r
- llfields.append((mangled_name, r.lowleveltype))
+ if self.gcflavor == 'gc':
+ r, internal_r = externalvsinternalfield(self.rtyper, r)
+ else:
+ internal_r = r
+ fields[name] = mangled_name, r, internal_r
+ llfields.append((mangled_name, internal_r.lowleveltype))
self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
self.gcflavor)
@@ -394,7 +400,7 @@
return getinstancerepr(self.rtyper, None, self.gcflavor)
def _get_field(self, attr):
- return self.fields[attr]
+ return self.fields[attr][:2]
def null_instance(self):
return nullptr(self.object_type)
@@ -410,7 +416,7 @@
# recursively build the parent part of the instance
self.rbase.initialize_prebuilt_data(value, classdef, result.super)
# then add instance attributes from this level
- for name, (mangled_name, r) in self.fields.items():
+ for name, (mangled_name, _, r) in self.fields.items():
if r.lowleveltype is Void:
llattrvalue = None
else:
@@ -440,7 +446,7 @@
def getfieldrepr(self, attr):
"""Return the repr used for the given attribute."""
if attr in self.fields:
- mangled_name, r = self.fields[attr]
+ mangled_name, r, internal_r = self.fields[attr]
return r
else:
if self.classdef is None:
@@ -450,12 +456,13 @@
def getfield(self, vinst, attr, llops, force_cast=False, flags={}):
"""Read the given attribute (or __class__ for the type) of 'vinst'."""
if attr in self.fields:
- mangled_name, r = self.fields[attr]
+ mangled_name, r, internal_r = self.fields[attr]
cname = inputconst(Void, mangled_name)
if force_cast:
vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
self.hook_access_field(vinst, cname, llops, flags)
- return llops.genop('getfield', [vinst, cname], resulttype=r)
+ v = llops.genop('getfield', [vinst, cname], resulttype=internal_r)
+ return llops.convertvar(v, internal_r, r)
else:
if self.classdef is None:
raise MissingRTypeAttribute(attr)
@@ -466,7 +473,8 @@
flags={}):
"""Write the given attribute (or __class__ for the type) of 'vinst'."""
if attr in self.fields:
- mangled_name, r = self.fields[attr]
+ mangled_name, r, internal_r = self.fields[attr]
+ vvalue = llops.convertvar(vvalue, r, internal_r)
cname = inputconst(Void, mangled_name)
if force_cast:
vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
@@ -499,7 +507,7 @@
for fldname in flds:
if fldname == '__class__':
continue
- mangled_name, r = self.allinstancefields[fldname]
+ mangled_name, r, internal_r = self.allinstancefields[fldname]
if r.lowleveltype is Void:
continue
value = self.classdef.classdesc.read_attribute(fldname, None)
Added: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rcompressed.py
==============================================================================
--- (empty file)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rcompressed.py Mon Oct 4 15:30:22 2010
@@ -0,0 +1,57 @@
+from pypy.tool.pairtype import pairtype
+from pypy.rlib.objectmodel import we_are_translated
+from pypy.config.translationoption import IS_64_BITS
+from pypy.rpython.rmodel import Repr, inputconst
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+
+
+
+def get_compressed_gcref_repr(rtyper, baserepr):
+ try:
+ comprmgr = rtyper.compressed_gcref_manager
+ except AttributeError:
+ comprmgr = rtyper.compressed_gcref_manager = ComprGcRefManager(rtyper)
+ return comprmgr.get_compressed_gcref_repr(baserepr)
+
+
+class ComprGcRefManager(object):
+ def __init__(self, rtyper):
+ assert IS_64_BITS # this is only for 64-bits
+ self.rtyper = rtyper
+ self.comprgcreprs = {}
+
+ def get_compressed_gcref_repr(self, baserepr):
+ try:
+ return self.comprgcreprs[baserepr]
+ except KeyError:
+ comprgcrepr = CompressedGcRefRepr(self, baserepr)
+ self.comprgcreprs[baserepr] = comprgcrepr
+ return comprgcrepr
+
+
+class CompressedGcRefRepr(Repr):
+ lowleveltype = llmemory.HiddenGcRef32
+
+ def __init__(self, mgr, baserepr):
+ self.mgr = mgr
+ self.baserepr = baserepr
+ self.BASETYPE = self.baserepr.lowleveltype
+
+ def convert_const(self, value):
+ ptr = self.baserepr.convert_const(value)
+ T = lltype.typeOf(ptr)
+ assert T == self.BASETYPE
+ return llmemory._hiddengcref32(llmemory.cast_ptr_to_adr(ptr))
+
+
+class __extend__(pairtype(Repr, CompressedGcRefRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ assert r_from.lowleveltype.TO._gckind == 'gc'
+ return llops.genop('hide_into_adr32', [v],
+ resulttype=llmemory.HiddenGcRef32)
+
+class __extend__(pairtype(CompressedGcRefRepr, Repr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ assert r_to.lowleveltype.TO._gckind == 'gc'
+ return llops.genop('show_from_adr32', [v],
+ resulttype=r_to.lowleveltype)
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/lltypesystem/rffi.py Mon Oct 4 15:30:22 2010
@@ -805,6 +805,8 @@
return 8
if tp is lltype.SingleFloat:
return 4
+ if tp is llmemory.HiddenGcRef32:
+ return 4
assert isinstance(tp, lltype.Number)
if tp is lltype.Signed:
return ULONG._type.BITS/8
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/base.py Mon Oct 4 15:30:22 2010
@@ -1,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
+from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rlib.debug import ll_assert
from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
@@ -168,8 +169,10 @@
def trace(self, obj, callback, arg):
"""Enumerate the locations inside the given obj that can contain
- GC pointers. For each such location, callback(pointer, arg) is
- called, where 'pointer' is an address inside the object.
+ GC pointers. For each such GC pointer, callback(object, arg) is
+ called, where 'object' is the address of the stored object.
+ 'callback' can return a new address that replaces the old one in
+ 'obj', or it can return None.
Typically, 'callback' is a bound method and 'arg' can be None.
"""
typeid = self.get_type_id(obj)
@@ -179,16 +182,16 @@
item = obj + llmemory.gcarrayofptr_itemsoffset
while length > 0:
if self.points_to_valid_gc_object(item):
- callback(item, arg)
+ newaddr = callback(item.address[0], arg)
+ if newaddr is not None:
+ item.address[0] = newaddr
item += llmemory.gcarrayofptr_singleitemoffset
length -= 1
return
offsets = self.offsets_to_gc_pointers(typeid)
i = 0
while i < len(offsets):
- item = obj + offsets[i]
- if self.points_to_valid_gc_object(item):
- callback(item, arg)
+ self._trace_see(obj, offsets[i], callback, arg)
i += 1
if self.has_gcptr_in_varsize(typeid):
item = obj + self.varsize_offset_to_variable_part(typeid)
@@ -198,14 +201,35 @@
while length > 0:
j = 0
while j < len(offsets):
- itemobj = item + offsets[j]
- if self.points_to_valid_gc_object(itemobj):
- callback(itemobj, arg)
+ self._trace_see(item, offsets[j], callback, arg)
j += 1
item += itemlength
length -= 1
trace._annspecialcase_ = 'specialize:arg(2)'
+ def _trace_see(self, obj, ofs, callback, arg):
+ if self.config.compressptr and llmemory.has_odd_value_marker(ofs):
+ # special handling of HiddenGcRef32 on 64-bit platforms
+ ofs = llmemory.remove_odd_value_marker(ofs)
+ item = obj + ofs
+ address = llop.show_from_adr32(llmemory.Address,
+ item.hiddengcref32[0])
+ if self.is_valid_gc_object(address):
+ newaddr = callback(address, arg)
+ if newaddr is not None:
+ newaddr32 = llop.hide_into_adr32(llmemory.HiddenGcRef32,
+ newaddr)
+ item.hiddengcref32[0] = newaddr32
+ else:
+ # common case
+ item = obj + ofs
+ if self.points_to_valid_gc_object(item):
+ newaddr = callback(item.address[0], arg)
+ if newaddr is not None:
+ item.address[0] = newaddr
+ _trace_see._annspecialcase_ = 'specialize:arg(3)'
+ _trace_see._always_inline_ = True
+
def trace_partial(self, obj, start, stop, callback, arg):
"""Like trace(), but only walk the array part, for indices in
range(start, stop). Must only be called if has_gcptr_in_varsize().
@@ -218,7 +242,9 @@
item += llmemory.gcarrayofptr_singleitemoffset * start
while length > 0:
if self.points_to_valid_gc_object(item):
- callback(item, arg)
+ newaddr = callback(item.address[0], arg)
+ if newaddr is not None:
+ item.address[0] = newaddr
item += llmemory.gcarrayofptr_singleitemoffset
length -= 1
return
@@ -231,9 +257,7 @@
while length > 0:
j = 0
while j < len(offsets):
- itemobj = item + offsets[j]
- if self.points_to_valid_gc_object(itemobj):
- callback(itemobj, arg)
+ self._trace_see(item, offsets[j], callback, arg)
j += 1
item += itemlength
length -= 1
@@ -279,8 +303,7 @@
obj = root.address[0]
ll_assert(bool(obj), "NULL address from walk_roots()")
self._debug_record(obj)
- def _debug_callback2(self, pointer, ignored):
- obj = pointer.address[0]
+ def _debug_callback2(self, obj, ignored):
ll_assert(bool(obj), "NULL address from self.trace()")
self._debug_record(obj)
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/minimark.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gc/minimark.py Mon Oct 4 15:30:22 2010
@@ -1025,19 +1025,17 @@
def _trace_drag_out1(self, root):
- self._trace_drag_out(root, None)
+ root.address[0] = self._trace_drag_out(root.address[0], None)
- def _trace_drag_out(self, root, ignored):
- obj = root.address[0]
+ def _trace_drag_out(self, obj, ignored):
#
# If 'obj' is not in the nursery, nothing to change.
if not self.is_in_nursery(obj):
- return
+ return obj
#
# If 'obj' was already forwarded, change it to its forwarding address.
if self.is_forwarded(obj):
- root.address[0] = self.get_forwarding_address(obj)
- return
+ return self.get_forwarding_address(obj)
#
# First visit to 'obj': we must move it out of the nursery.
size_gc_header = self.gcheaderbuilder.size_gc_header
@@ -1075,14 +1073,14 @@
newobj = newhdr + size_gc_header
llmemory.cast_adr_to_ptr(obj, FORWARDSTUBPTR).forw = newobj
#
- # Change the original pointer to this object.
- root.address[0] = newobj
- #
# Add the newobj to the list 'old_objects_pointing_to_young',
# because it can contain further pointers to other young objects.
# We will fix such references to point to the copy of the young
# objects when we walk 'old_objects_pointing_to_young'.
self.old_objects_pointing_to_young.append(newobj)
+ #
+ # Change the original pointer to this newly built object.
+ return newobj
def _malloc_out_of_nursery(self, totalsize):
@@ -1279,8 +1277,8 @@
def _collect_ref(self, root):
self.objects_to_trace.append(root.address[0])
- def _collect_ref_rec(self, root, ignored):
- self.objects_to_trace.append(root.address[0])
+ def _collect_ref_rec(self, obj, ignored):
+ self.objects_to_trace.append(obj)
def visit_all_objects(self):
pending = self.objects_to_trace
@@ -1421,8 +1419,8 @@
self.objects_with_finalizers.delete()
self.objects_with_finalizers = new_with_finalizer
- def _append_if_nonnull(pointer, stack):
- stack.append(pointer.address[0])
+ def _append_if_nonnull(obj, stack):
+ stack.append(obj)
_append_if_nonnull = staticmethod(_append_if_nonnull)
def _finalization_state(self, obj):
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gctypelayout.py Mon Oct 4 15:30:22 2010
@@ -16,6 +16,8 @@
"""
_alloc_flavor_ = 'raw'
+ # if config.translation.compressptr, the OFFSETS_TO_GC_PTR lists
+ # as odd integers the fields that are compressed pointers (UINT).
OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed)
ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
FINALIZERTYPE = lltype.Ptr(ADDRESS_VOID_FUNC)
@@ -389,6 +391,8 @@
# (adr + off)
elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
offsets.append(0)
+ elif TYPE == llmemory.HiddenGcRef32:
+ offsets.append(llmemory.OddValueMarker())
return offsets
def gc_pointers_inside(v, adr, mutable_only=False):
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gcwrapper.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/gcwrapper.py Mon Oct 4 15:30:22 2010
@@ -88,7 +88,9 @@
def setinterior(self, toplevelcontainer, inneraddr, INNERTYPE, newvalue,
offsets=()):
if (lltype.typeOf(toplevelcontainer).TO._gckind == 'gc' and
- isinstance(INNERTYPE, lltype.Ptr) and INNERTYPE.TO._gckind == 'gc'):
+ (isinstance(INNERTYPE, lltype.Ptr) and
+ INNERTYPE.TO._gckind == 'gc')
+ or INNERTYPE == llmemory.HiddenGcRef32):
#
wb = True
if self.has_write_barrier_from_array:
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gc.py Mon Oct 4 15:30:22 2010
@@ -77,6 +77,23 @@
#assert simulator.current_size - curr < 16000 * INT_SIZE / 4
#print "size before: %s, size after %s" % (curr, simulator.current_size)
+ def test_llinterp_instances(self):
+ class Cons(object):
+ def __init__(self, car, cdr):
+ self.car = car
+ self.cdr = cdr
+ def malloc_a_lot():
+ i = 0
+ while i < 10:
+ i += 1
+ a = Cons(1, Cons(2, Cons(i, None)))
+ b = a
+ j = 0
+ while j < 20:
+ j += 1
+ b = Cons(j, b)
+ res = self.interpret(malloc_a_lot, [])
+
def test_global_list(self):
lst = []
def append_to_list(i, j):
@@ -776,3 +793,20 @@
class TestMiniMarkGCCardMarking(TestMiniMarkGC):
GC_PARAMS = {'card_page_indices': 4}
+
+class TestMiniMarkGCCompressPtr(TestMiniMarkGC):
+ def setup_class(cls):
+ TestMiniMarkGC.setup_class.im_func(cls)
+ #
+ from pypy.config.translationoption import IS_64_BITS
+ if not IS_64_BITS:
+ py.test.skip("only for 64-bits")
+ from pypy.config.pypyoption import get_pypy_config
+ cls._config = get_pypy_config(translating=True)
+ cls._config.translation.compressptr = True
+
+ def interpret(self, *args, **kwds):
+ if kwds.get('taggedpointers'):
+ py.test.skip("cannot have both taggedpointers and compressptr")
+ kwds['config'] = self._config
+ return super(TestMiniMarkGCCompressPtr, self).interpret(*args, **kwds)
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gctypelayout.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gctypelayout.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/memory/test/test_gctypelayout.py Mon Oct 4 15:30:22 2010
@@ -37,6 +37,15 @@
for T, c in [(GC_S, 0), (GC_S2, 2), (GC_A, 0), (GC_A2, 0), (GC_S3, 2)]:
assert len(offsets_to_gc_pointers(T)) == c
+def test_hiddenptr32():
+ from pypy.rpython.lltypesystem.llmemory import HIDDENPTR32
+ from pypy.rpython.lltypesystem.llmemory import has_odd_value_marker
+ T = lltype.GcStruct('T', ('foo', lltype.Ptr(GC_S3)), ('bar', HIDDENPTR32))
+ ofs = offsets_to_gc_pointers(T)
+ assert len(ofs) == 2
+ assert not has_odd_value_marker(ofs[0])
+ assert has_odd_value_marker(ofs[1])
+
def test_layout_builder(lltype2vtable=None):
# XXX a very minimal test
layoutbuilder = TypeLayoutBuilder(FakeGC, lltype2vtable)
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/raddress.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/raddress.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/raddress.py Mon Oct 4 15:30:22 2010
@@ -2,7 +2,7 @@
from pypy.tool.pairtype import pairtype
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem.llmemory import NULL, Address, \
- cast_adr_to_int, fakeaddress
+ cast_adr_to_int, fakeaddress, HiddenGcRef32, _hiddengcref32
from pypy.rpython.rmodel import Repr, IntegerRepr
from pypy.rpython.rptr import PtrRepr
from pypy.rpython.lltypesystem import lltype
@@ -24,6 +24,13 @@
def rtyper_makekey(self):
return self.__class__, self.type
+class __extend__(annmodel.SomeHiddenGcRef32):
+ def rtyper_makerepr(self, rtyper):
+ return hiddengcref32_repr
+
+ def rtyper_makekey(self):
+ return self.__class__,
+
class AddressRepr(Repr):
lowleveltype = Address
@@ -139,4 +146,13 @@
def convert_from_to((r_ptr, r_addr), v, llops):
return llops.genop('cast_ptr_to_adr', [v], resulttype=Address)
+# ____________________________________________________________
+
+class HiddenGcRef32Repr(Repr):
+ lowleveltype = HiddenGcRef32
+
+ def convert_const(self, value):
+ assert isinstance(value, _hiddengcref32)
+ return value
+hiddengcref32_repr = HiddenGcRef32Repr()
Modified: pypy/branch/32ptr-on-64bit/pypy/rpython/rmodel.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/rpython/rmodel.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/rmodel.py Mon Oct 4 15:30:22 2010
@@ -438,9 +438,21 @@
from pypy.rpython import rclass
if (isinstance(item_repr, rclass.AbstractInstanceRepr) and
getattr(item_repr, 'gcflavor', 'gc') == 'gc'):
+ #if rtyper.annotator.translator.config.translation.compressptr:
+ # return externalvsinternalfield(rtyper, item_repr)
return item_repr, rclass.getinstancerepr(rtyper, None)
- else:
- return item_repr, item_repr
+ return item_repr, item_repr
+
+def externalvsinternalfield(rtyper, field_repr):
+ # usually a no-op, except if config.translation.compressptr, in which case
+ # it tries hard to return a wrapping compressed_gcref_repr
+ if rtyper.annotator.translator.config.translation.compressptr:
+ if (isinstance(field_repr.lowleveltype, Ptr) and
+ field_repr.lowleveltype.TO._gckind == 'gc'):
+ from pypy.rpython.lltypesystem import rcompressed
+ return (field_repr,
+ rcompressed.get_compressed_gcref_repr(rtyper, field_repr))
+ return field_repr, field_repr
class DummyValueBuilder(object):
Added: pypy/branch/32ptr-on-64bit/pypy/rpython/test/test_rcompressed.py
==============================================================================
--- (empty file)
+++ pypy/branch/32ptr-on-64bit/pypy/rpython/test/test_rcompressed.py Mon Oct 4 15:30:22 2010
@@ -0,0 +1,28 @@
+import py
+from pypy.config.translationoption import IS_64_BITS
+from pypy.rpython.test import test_rclass
+
+
+def setup_module(mod):
+ if not IS_64_BITS:
+ py.test.skip("for 64-bits only")
+
+
+class MixinCompressed64(object):
+ def _get_config(self):
+ from pypy.config.pypyoption import get_pypy_config
+ config = get_pypy_config(translating=True)
+ config.translation.compressptr = True
+ return config
+
+ def interpret(self, *args, **kwds):
+ kwds['config'] = self._get_config()
+ return super(MixinCompressed64, self).interpret(*args, **kwds)
+
+ def interpret_raises(self, *args, **kwds):
+ kwds['config'] = self._get_config()
+ return super(MixinCompressed64, self).interpret_raises(*args, **kwds)
+
+
+class TestLLtype64(MixinCompressed64, test_rclass.TestLLtype):
+ pass
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/database.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/database.py Mon Oct 4 15:30:22 2010
@@ -55,6 +55,7 @@
# assign to a constant object is something C doesn't think is
# constant
self.late_initializations = []
+ self.late_initializations_hiddengcref32 = []
self.namespace = CNameManager()
if translator is None or translator.rtyper is None:
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/node.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/node.py Mon Oct 4 15:30:22 2010
@@ -771,25 +771,33 @@
yield '}'
def generic_initializationexpr(db, value, access_expr, decoration):
- if isinstance(typeOf(value), ContainerType):
+ TYPE = typeOf(value)
+ if isinstance(TYPE, ContainerType):
node = db.getcontainernode(value)
lines = list(node.initializationexpr(decoration+'.'))
lines[-1] += ','
return lines
else:
comma = ','
- if typeOf(value) == Ptr(PyObject) and value:
+ if TYPE == Ptr(PyObject) and value:
# cannot just write 'gxxx' as a constant in a structure :-(
node = db.getcontainernode(value._obj)
expr = 'NULL /*%s*/' % node.name
node.where_to_copy_me.append('&%s' % access_expr)
- elif typeOf(value) == Float and (isinf(value) or isnan(value)):
- db.late_initializations.append(('%s' % access_expr, db.get(value)))
+ elif TYPE == Float and (isinf(value) or isnan(value)):
+ db.late_initializations.append((access_expr, db.get(value)))
expr = '0.0 /* patched later by %sinfinity */' % (
'-+'[value > 0])
+ elif TYPE == llmemory.HiddenGcRef32:
+ if value.adr64:
+ db.late_initializations_hiddengcref32.append((access_expr,
+ value))
+ expr = '0 /*HIDE_INTO_ADR32%s*/' % db.get(value.adr64.ptr)
+ else:
+ expr = '0'
else:
expr = db.get(value)
- if typeOf(value) is Void:
+ if TYPE is Void:
comma = ''
expr += comma
i = expr.find('\n')
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/primitive.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/primitive.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/primitive.py Mon Oct 4 15:30:22 2010
@@ -7,7 +7,7 @@
from pypy.rpython.lltypesystem.llmemory import Address, \
AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
CompositeOffset, ArrayLengthOffset, \
- GCHeaderOffset, GCREF, AddressAsInt
+ GCHeaderOffset, GCREF, AddressAsInt, HiddenGcRef32, OddValueMarker
from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
from pypy.translator.c.support import cdecl, barebonearray
@@ -63,6 +63,8 @@
return '(%s+%dL)' % (name, value.rest)
elif isinstance(value, AddressAsInt):
return '((long)%s)' % name_address(value.adr, db)
+ elif isinstance(value, OddValueMarker):
+ return '1 /*OddValueMarker*/'
else:
raise Exception("unimplemented symbolic %r"%value)
if value is None:
@@ -145,6 +147,12 @@
else:
return 'NULL'
+def name_hiddengcref32(value, db):
+ # The only prebuilt HiddenGcRef32 that should occur in a translated C
+ # program occur as fields or items of a GcStruct or GcArray.
+ db.get(value.adr64)
+ return 'HIDE_INTO_ADR32(???) /* see primitive.py, name_hiddengcref32() */'
+
def name_small_integer(value, db):
"""Works for integers of size at most INT or UINT."""
if isinstance(value, Symbolic):
@@ -173,6 +181,7 @@
Void: name_void,
Address: name_address,
GCREF: name_gcref,
+ HiddenGcRef32: name_hiddengcref32,
}
PrimitiveType = {
@@ -188,6 +197,7 @@
Void: 'void @',
Address: 'void* @',
GCREF: 'void* @',
+ HiddenGcRef32: 'hiddengcref32_t @',
}
def define_c_primitive(ll_type, c_name, suffix=''):
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/src/commondefs.h
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/src/commondefs.h (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/src/commondefs.h Mon Oct 4 15:30:22 2010
@@ -65,6 +65,15 @@
# define SIZEOF_LONG 8
# define SIZEOF_LONG_LONG 8
+ /* HiddenGcRef32 support (on 64-bits only) */
+ typedef unsigned int hiddengcref32_t;
+# define uint32_t hiddengcref32_t
+# define OP_SHOW_FROM_ADR32(x, r) r = (void*)(((unsigned long)(x)) << 3)
+# define OP_HIDE_INTO_ADR32(x, r) \
+ r = (hiddengcref32_t)(((unsigned long)(x)) >> 3); \
+ RPyAssert((void*)(((unsigned long)(r)) << 3) == (x), \
+ "pointer too big or misaligned!")
+
#endif
/********************************************************/
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_lladdresses.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_lladdresses.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_lladdresses.py Mon Oct 4 15:30:22 2010
@@ -232,3 +232,43 @@
assert res == 456
res = fc(77)
assert res == 123
+
+
+##class TestHiddenGcRef32(StandaloneTests):
+
+## def setup_class(cls):
+## from pypy.config.translationoption import IS_64_BITS
+## if 0:# not IS_64_BITS:
+## py.test.skip("only for 64-bits")
+
+## def test_hiddengcref32(self):
+## from pypy.rpython.lltypesystem.lloperation import llop
+## S = lltype.GcStruct('S', ('x', lltype.Signed),
+## ('y', HiddenGcRef32))
+## prebuilt = lltype.malloc(S, immortal=True)
+## prebuilt2 = lltype.malloc(S, immortal=True)
+## prebuilt.x = 42
+## prebuilt2.x = 53
+## prebuilt.y = llop.hide_into_adr32(HiddenGcRef32, prebuilt2)
+## prebuilt2.y = llop.hide_into_adr32(HiddenGcRef32, prebuilt)
+
+## def check(a, b):
+## p = llop.show_from_adr32(lltype.Ptr(S), a.y)
+## assert p == b
+
+## def f(argv):
+## assert prebuilt.x == 42
+## assert prebuilt2.x == 53
+## check(prebuilt, prebuilt2)
+## check(prebuilt2, prebuilt)
+## p = lltype.malloc(S)
+## p.y = llop.hide_into_adr32(HiddenGcRef32, prebuilt)
+## prebuilt2.y = llop.hide_into_adr32(HiddenGcRef32, p)
+## check(p, prebuilt)
+## check(prebuilt2, p)
+## check(prebuilt, prebuilt2)
+## return 0
+
+## fc = self.compile(f)
+## res = fc([])
+## assert res == 0
Modified: pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_newgc.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/translator/c/test/test_newgc.py Mon Oct 4 15:30:22 2010
@@ -18,6 +18,7 @@
should_be_moving = False
removetypeptr = False
taggedpointers = False
+ compressptr = False
GC_CAN_MOVE = False
GC_CAN_MALLOC_NONMOVABLE = True
GC_CAN_SHRINK_ARRAY = False
@@ -41,7 +42,8 @@
t = Translation(main, standalone=True, gc=cls.gcpolicy,
policy=annpolicy.StrictAnnotatorPolicy(),
taggedpointers=cls.taggedpointers,
- gcremovetypeptr=cls.removetypeptr)
+ gcremovetypeptr=cls.removetypeptr,
+ compressptr=cls.compressptr)
t.disable(['backendopt'])
t.set_backend_extra_options(c_debug_defines=True)
t.rtype()
@@ -623,7 +625,7 @@
assert open(self.filename, 'r').read() == "hello world\n"
os.unlink(self.filename)
- def define_callback_with_collect(cls):
+ def XXXXXXXXXdefine_callback_with_collect(cls):
from pypy.rlib.libffi import ffi_type_pointer, cast_type_to_ffitype,\
CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint
from pypy.rpython.lltypesystem import rffi, ll2ctypes
@@ -1333,6 +1335,15 @@
def test_gc_heap_stats(self):
py.test.skip("not implemented")
+class TestMiniMarkGCCompressPtr(TestMiniMarkGC):
+ compressptr = True
+
+ def setup_class(cls):
+ from pypy.config.translationoption import IS_64_BITS
+ if not IS_64_BITS:
+ py.test.skip("only for 64-bits")
+ TestMiniMarkGC.setup_class.im_func(cls)
+
# ____________________________________________________________________
class TaggedPointersTest(object):
More information about the Pypy-commit
mailing list