Author: Richard Plangger <[email protected]>
Branch: strbuf-as-buffer
Changeset: r89194:331d137617e6
Date: 2016-12-20 10:28 +0100
http://bitbucket.org/pypy/pypy/changeset/331d137617e6/
Log: experiment with a new llop called move_out_of_nursery
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -729,6 +729,14 @@
obj = self.external_malloc(typeid, length, alloc_young=True)
return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+ def move_out_of_nursery(self, obj):
+ #
+ size_gc_header = self.gcheaderbuilder.size_gc_header
+ totalsize = size_gc_header + self.get_size(obj)
+ self.nursery_surviving_size += raw_malloc_usage(totalsize)
+ newhdr = self._malloc_out_of_nursery(totalsize)
+ #return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+
def collect(self, gen=2):
"""Do a minor (gen=0), start a major (gen=1), or do a full
diff --git a/rpython/memory/gctransform/framework.py
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -551,6 +551,13 @@
[s_gc, SomeAddress()],
annmodel.s_None)
+ self.move_out_of_nursery_ptr = None
+ if hasattr(GCClass, 'move_out_of_nursery'):
+ self.move_out_of_nursery_ptr = getfn(GCClass.move_out_of_nursery,
+ [s_gc, SomeAddress()],
+ SomeAddress())
+
+
def create_custom_trace_funcs(self, gc, rtyper):
custom_trace_funcs = tuple(rtyper.custom_trace_funcs)
rtyper.custom_trace_funcs = custom_trace_funcs
@@ -1585,6 +1592,14 @@
hop.genop("direct_call", [self.ignore_finalizer_ptr,
self.c_const_gc, v_adr])
+ def gct_gc_move_out_of_nursery(self, hop):
+ if self.move_out_of_nursery_ptr is not None:
+ v_adr = hop.genop("cast_ptr_to_adr", [hop.spaceop.args[0]],
+ resulttype=llmemory.Address)
+ hop.genop("direct_call", [self.move_out_of_nursery_ptr,
+ self.c_const_gc, v_adr])
+
+
class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder):
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -78,7 +78,7 @@
return [1]
class StringBuffer(Buffer):
- __slots__ = ['value', '__weakref__']
+ __slots__ = ['value']
_immutable_ = True
def __init__(self, value):
@@ -109,7 +109,7 @@
def get_raw_address(self):
from rpython.rtyper.lltypesystem import rffi
- return rffi.get_raw_address_of_string(self, self.value)
+ return rffi.get_raw_address_of_string(self.value)
class SubBuffer(Buffer):
__slots__ = ['buffer', 'offset', 'size']
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -535,6 +535,13 @@
from rpython.rtyper.lltypesystem.lloperation import llop
llop.gc_ignore_finalizer(lltype.Void, obj)
[email protected]_look_inside
+def move_out_of_nursery(obj):
+ """This object should move to the second generation (out of nursery).
+ The object will not move, anymore after this operation succeeded.
+ """
+ from rpython.rtyper.lltypesystem.lloperation import llop
+ llop.gc_move_out_of_nursery(obj)
# ____________________________________________________________
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -494,6 +494,8 @@
'gc_rawrefcount_from_obj': LLOp(sideeffects=False),
'gc_rawrefcount_to_obj': LLOp(sideeffects=False),
+ 'gc_move_out_of_nursery': LLOp(),
+
# ------- JIT & GC interaction, only for some GCs ----------
'gc_adr_of_nursery_free' : LLOp(),
diff --git a/rpython/rtyper/lltypesystem/opimpl.py
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -739,6 +739,9 @@
def op_gc_ignore_finalizer(obj):
pass
+def op_gc_move_out_of_nursery(obj):
+ return obj
+
# ____________________________________________________________
def get_op_impl(opname):
diff --git a/rpython/rtyper/lltypesystem/rffi.py
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -1320,14 +1320,14 @@
def __del__(self):
free_charp(self.ptr, track_allocation=False)
-from rpython.rlib import rweakref
-from rpython.rlib.buffer import Buffer
-_STR_WDICT = rweakref.RWeakKeyDictionary(Buffer, RawBytes)
+if not we_are_translated():
+ TEST_RAW_ADDR_KEEP_ALIVE = {}
@jit.dont_look_inside
-def get_raw_address_of_string(key, string):
- """Returns a 'char *' that is valid as long as the key object is alive.
- Two calls to to this function are guaranteed to return the same pointer.
+def get_raw_address_of_string(string):
+ """Returns a 'char *' that is valid as long as the rpython string object
is alive.
+ Two calls to to this function, given the same string parameter,
+ are guaranteed to return the same pointer.
The extra parameter key is necessary to create a weak reference.
The buffer of the returned pointer (if object is young) lives as long
@@ -1335,24 +1335,28 @@
be freed. `string` cannot go out of scope until the RawBytes object
referencing it goes out of scope.
"""
+ assert isinstance(string, str)
from rpython.rtyper.annlowlevel import llstr
from rpython.rtyper.lltypesystem.rstr import STR
from rpython.rtyper.lltypesystem import llmemory
from rpython.rlib import rgc
- global _STR_WDICT
- rawbytes = _STR_WDICT.get(key)
- if rawbytes is None:
- if we_are_translated() and not rgc.can_move(string):
- lldata = llstr(string)
- data_start = (llmemory.cast_ptr_to_adr(lldata) +
- offsetof(STR, 'chars') +
- llmemory.itemoffsetof(STR.chars, 0))
- data_start = cast(CCHARP, data_start)
- data_start[len(string)] = '\x00' # write the final extra null
- return data_start
- rawbytes = RawBytes(string)
- _STR_WDICT.set(key, rawbytes)
+ if we_are_translated():
+ if rgc.can_move(string):
+ string = rgc.move_out_of_nursery(string)
- return rawbytes.ptr
-
+ assert not rgc.can_move(string)
+ # string cannot move! just return the address then!
+ lldata = llstr(string)
+ data_start = (llmemory.cast_ptr_to_adr(lldata) +
+ offsetof(STR, 'chars') +
+ llmemory.itemoffsetof(STR.chars, 0))
+ data_start = cast(CCHARP, data_start)
+ data_start[len(string)] = '\x00' # write the final extra null
+ return data_start
+ else:
+ global TEST_RAW_ADDR_KEEP_ALIVE
+ if string in TEST_RAW_ADDR_KEEP_ALIVE:
+ return TEST_RAW_ADDR_KEEP_ALIVE[string].ptr
+ TEST_RAW_ADDR_KEEP_ALIVE[string] = rb = RawBytes(string)
+ return rb.ptr
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit