Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r54806:56bc17590024
Date: 2012-04-29 14:29 +0200
http://bitbucket.org/pypy/pypy/changeset/56bc17590024/
Log: Manually backout most of 133049a5ba84.
The idea doesn't work as it is. The issue is what occurs in case a
transaction is aborted. The thread-local data cannot stay around
for the next transaction, because it now points to half-random data.
:-(
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -86,8 +86,7 @@
# code (see tldict_lookup()).
#
# Invariant: between two transactions, all objects visible from the current
-# thread are always GLOBAL, with the exception of the ones only reachable
-# via thread-local data structures, which remain LOCAL. In particular:
+# thread are always GLOBAL. In particular:
#
# - The LOCAL objects of a thread are not visible at all from other threads.
# This means that in transactional mode there is *no* pointer from a
@@ -95,8 +94,6 @@
#
# - At the end of enter_transactional_mode(), and at the beginning of
# leave_transactional_mode(), *all* objects everywhere are GLOBAL.
-# (With the possible exception of the thread-local ones from the main
-# thread.)
#
# Collection: for now we have only local_collection(), which ignores all
# GLOBAL objects.
@@ -113,11 +110,9 @@
#
# - A special case is the end-of-transaction collection, done by the same
# local_collection() with a twist: all pointers to a LOCAL COPY object
-# are replaced with copies to the corresponding GLOBAL original.
-# We additionally mark all surviving LOCAL objects as GLOBAL,
-# unless they are only reachable via thread-locals.
-# Then we are back to the situation where this thread sees only
-# GLOBAL objects (again, with the exception of thread-locals).
+# are replaced with copies to the corresponding GLOBAL original. When
+# it is done, we mark all surviving LOCAL objects as GLOBAL too, and we
+# are back to the situation where this thread sees only GLOBAL objects.
# What we leave to the C code to do "as a finishing touch" is to copy
# transactionally the content of the LOCAL COPY objects back over the
# GLOBAL originals; before this is done, the transaction can be aborted
@@ -168,7 +163,6 @@
#needs_write_barrier = "stm"
prebuilt_gc_objects_are_static_roots = False
malloc_zero_filled = True # xxx?
- handles_thread_locals = True
HDR = lltype.Struct('header', ('tid', lltype.Signed),
('version', llmemory.Address))
diff --git a/pypy/rpython/memory/gctransform/framework.py
b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -168,7 +168,6 @@
a_random_address = llmemory.cast_ptr_to_adr(foo)
gcdata.static_root_start = a_random_address # patched in finish()
gcdata.static_root_nongcend = a_random_address # patched in finish()
- gcdata.static_root_thrlocend = a_random_address # patched in finish()
gcdata.static_root_end = a_random_address # patched in finish()
gcdata.max_type_id = 13 # patched in finish()
gcdata.typeids_z = a_random_address # patched in finish()
@@ -208,9 +207,6 @@
'static_root_nongcend',
annmodel.SomeAddress())
data_classdef.generalize_attr(
- 'static_root_thrlocend',
- annmodel.SomeAddress())
- data_classdef.generalize_attr(
'static_root_end',
annmodel.SomeAddress())
data_classdef.generalize_attr(
@@ -587,11 +583,9 @@
r_gcdata = self.translator.rtyper.getrepr(s_gcdata)
ll_instance = rmodel.inputconst(r_gcdata, self.gcdata).value
- lb = self.layoutbuilder
addresses_of_static_ptrs = (
- lb.addresses_of_static_ptrs_in_nongc +
- lb.addresses_of_static_getters_thrloc +
- lb.addresses_of_static_ptrs)
+ self.layoutbuilder.addresses_of_static_ptrs_in_nongc +
+ self.layoutbuilder.addresses_of_static_ptrs)
log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
len(addresses_of_static_ptrs),
@@ -599,23 +593,9 @@
for i in range(len(addresses_of_static_ptrs)):
ll_static_roots_inside[i] = addresses_of_static_ptrs[i]
-
- ll_instance.inst_static_root_start = (
- llmemory.cast_ptr_to_adr(ll_static_roots_inside) +
- llmemory.ArrayItemsOffset(lltype.Array(llmemory.Address)))
- ll_instance.inst_static_root_nongcend = (
- ll_instance.inst_static_root_start +
- sizeofaddr * len(lb.addresses_of_static_ptrs_in_nongc))
- ll_instance.inst_static_root_thrlocend = (
- ll_instance.inst_static_root_nongcend +
- sizeofaddr * len(lb.addresses_of_static_getters_thrloc))
- ll_instance.inst_static_root_end = (
- ll_instance.inst_static_root_thrlocend +
- sizeofaddr * len(lb.addresses_of_static_ptrs))
- assert ll_instance.inst_static_root_end == (
- ll_instance.inst_static_root_start +
- sizeofaddr * len(addresses_of_static_ptrs))
-
+ ll_instance.inst_static_root_start =
llmemory.cast_ptr_to_adr(ll_static_roots_inside) +
llmemory.ArrayItemsOffset(lltype.Array(llmemory.Address))
+ ll_instance.inst_static_root_nongcend =
ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) *
len(self.layoutbuilder.addresses_of_static_ptrs_in_nongc)
+ ll_instance.inst_static_root_end = ll_instance.inst_static_root_start
+ llmemory.sizeof(llmemory.Address) * len(addresses_of_static_ptrs)
newgcdependencies = []
newgcdependencies.append(ll_static_roots_inside)
ll_instance.inst_max_type_id = len(group.members)
@@ -627,15 +607,6 @@
ll_typeids_z[i] = typeids_z[i]
ll_instance.inst_typeids_z = llmemory.cast_ptr_to_adr(ll_typeids_z)
newgcdependencies.append(ll_typeids_z)
- #
- if lb.addresses_of_static_getters_thrloc:
- annhelper = annlowlevel.MixLevelHelperAnnotator(
- self.translator.rtyper)
- for getter in lb.addresses_of_static_getters_thrloc:
- annhelper.getgraph(getter.ptr._obj._callable, [],
- annmodel.SomeAddress())
- annhelper.finish()
- #
return newgcdependencies
def get_finish_tables(self):
@@ -1403,8 +1374,7 @@
def walk_roots(self, collect_stack_root,
collect_static_in_prebuilt_nongc,
- collect_static_in_prebuilt_gc,
- collect_static_in_prebuilt_threadlocal=None):
+ collect_static_in_prebuilt_gc):
gcdata = self.gcdata
gc = self.gc
if collect_static_in_prebuilt_nongc:
@@ -1415,18 +1385,8 @@
if gc.points_to_valid_gc_object(result):
collect_static_in_prebuilt_nongc(gc, result)
addr += sizeofaddr
- if collect_static_in_prebuilt_threadlocal:
+ if collect_static_in_prebuilt_gc:
addr = gcdata.static_root_nongcend
- end = gcdata.static_root_thrlocend
- while addr != end:
- fadr = addr.address[0]
- fptr = llmemory.cast_adr_to_ptr(fadr, gctypelayout.GETTERFN)
- result = fptr()
- if gc.points_to_valid_gc_object(result):
- collect_static_in_prebuilt_threadlocal(gc, result)
- addr += sizeofaddr
- if collect_static_in_prebuilt_gc:
- addr = gcdata.static_root_thrlocend
end = gcdata.static_root_end
while addr != end:
result = addr.address[0]
diff --git a/pypy/rpython/memory/gctypelayout.py
b/pypy/rpython/memory/gctypelayout.py
--- a/pypy/rpython/memory/gctypelayout.py
+++ b/pypy/rpython/memory/gctypelayout.py
@@ -266,15 +266,11 @@
# the following are lists of addresses of gc pointers living inside the
# prebuilt structures. It should list all the locations that could
# possibly point to a GC heap object.
- # this lists contains pointers in GcStructs and GcArrays
+ # this list contains pointers in GcStructs and GcArrays
# (note that on some GCs, we don't need this, so it is empty)
self.addresses_of_static_ptrs = []
- # this lists contains pointers in raw Structs and Arrays
+ # this list contains pointers in raw Structs and Arrays
self.addresses_of_static_ptrs_in_nongc = []
- # this lists contains addresses of functions that just return
- # the thread-local address of a GC pointer from a raw Struct
- # with the 'stm_thread_local' hint.
- self.addresses_of_static_getters_thrloc = []
# for debugging, the following list collects all the prebuilt
# GcStructs and GcArrays
self.all_prebuilt_gc = []
@@ -430,28 +426,24 @@
adr = llmemory.cast_ptr_to_adr(value._as_ptr())
if TYPE._gckind == "gc":
if gc.prebuilt_gc_objects_are_static_roots or gc.DEBUG:
- append = self.addresses_of_static_ptrs.append
+ appendto = self.addresses_of_static_ptrs
else:
return
elif hasattr(TYPE, "_hints") and TYPE._hints.get('stm_thread_local'):
- assert gc.handles_thread_locals
- def append(a):
- def getter():
- return a
- from pypy.annotation import model as annmodel
- from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
- annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
- fptr = annhelper.delayedfunction(getter, [],
- annmodel.SomeAddress())
- annhelper.finish()
- adr = llmemory.cast_ptr_to_adr(fptr)
- self.addresses_of_static_getters_thrloc.append(adr)
+ # The exception data's value object is skipped: it's a thread-
+ # local data structure. We assume that objects are stored
+ # only temporarily there, so it is always cleared at the point
+ # where we collect the roots.
+ if TYPE._name == 'ExcData':
+ return
+ # Some other thread-local data don't have any GC pointers
+ # themselves. These are fine.
+ assert list(gc_pointers_inside(value, adr)) == []
+ return
else:
- append = self.addresses_of_static_ptrs_in_nongc.append
+ appendto = self.addresses_of_static_ptrs_in_nongc
for a in gc_pointers_inside(value, adr, mutable_only=True):
- append(a)
-
-GETTERFN = lltype.Ptr(lltype.FuncType([], llmemory.Address))
+ appendto.append(a)
# ____________________________________________________________
#
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit