Author: Armin Rigo <[email protected]>
Branch: stm-gc-2
Changeset: r63551:022708a2e72c
Date: 2013-04-22 17:40 +0200
http://bitbucket.org/pypy/pypy/changeset/022708a2e72c/
Log: intermediate check-in
diff --git a/rpython/memory/gc/stmshared.py b/rpython/memory/gc/stmshared.py
--- a/rpython/memory/gc/stmshared.py
+++ b/rpython/memory/gc/stmshared.py
@@ -115,7 +115,15 @@
self.objects_to_trace = self.AddressStack()
#
# The stacks...
- self.collect_stack_roots_from_every_thread()
+ self.collect_roots_from_stacks()
+ #
+ # The raw structures...
+ self.collect_from_raw_structures()
+ #
+ # The tldicts...
+ self.collect_roots_from_tldicts()
+ #
+ self.visit_all_objects()
#
self.num_major_collects += 1
debug_print("| used after collection: ",
@@ -125,16 +133,62 @@
debug_print("`----------------------------------------------")
debug_stop("gc-collect")
- def collect_stack_roots_from_every_thread(self):
- self.gc.root_walker.walk_all_stack_roots(self._collect_stack_root,
- None)
+ def collect_roots_from_stacks(self):
+
self.gc.root_walker.walk_all_stack_roots(StmGCSharedArea._collect_stack_root,
+ self)
- def _collect_stack_root(self, ignored, root):
- self.visit(root.address[0])
+ def collect_from_raw_structures(self):
+ self.gc.root_walker.walk_current_nongc_roots(
+ StmGCSharedArea._collect_stack_root, self)
+
+ def _collect_stack_root(self, root):
+ self.objects_to_trace.append(root.address[0])
+
+ def collect_roots_from_tldicts(self):
+ CALLBACK = self.gc.stm_operations.CALLBACK_ENUM
+ llop.nop(lltype.Void, llhelper(CALLBACK,
+
StmGCSharedArea._stm_enum_external_callback))
+ # The previous line causes the _stm_enum_external_callback() function
to be
+ # generated in the C source with a specific signature, where it
+ # can be called by the C code.
+ stmtls = self.gc.linked_list_stmtls
+ while stmtls is not None:
+ self.visit_all_objects() # empty the list first
+ # for every stmtls:
+
self.gc.stm_operations.tldict_enum_external(stmtls.thread_descriptor)
+ stmtls = stmtls.linked_list_next
+
+ @staticmethod
+ def _stm_enum_external_callback(globalobj, localobj):
+ localhdr = self.gc.header(localobj)
+ ll_assert(localhdr.tid & GCFLAG_VISITED != 0,
+ "[shared] in a root: missing GCFLAG_VISITED")
+ localhdr.tid &= ~GCFLAG_VISITED
+ self.objects_to_trace.append(localobj)
+ self.objects_to_trace.append(globalobj)
+
+ def visit_all_objects(self):
+ pending = self.objects_to_trace
+ while pending.non_empty():
+ obj = pending.pop()
+ self.visit(obj)
def visit(self, obj):
+ # 'obj' is a live object. Check GCFLAG_VISITED to know if we
+ # have already seen it before.
hdr = self.gc.header(obj)
- XXX
+ if hdr.tid & GCFLAG_VISITED:
+ return
+ #
+ # It's the first time. We set the flag.
+ hdr.tid |= GCFLAG_VISITED
+ #
+ # Trace the content of the object and put all objects it references
+ # into the 'objects_to_trace' list.
+ self.gc.trace(obj, self._collect_ref_rec, None)
+
+ def _collect_ref_rec(self, root, ignored):
+ self.objects_to_trace.append(root.address[0])
# ------------------------------------------------------------
diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py
--- a/rpython/memory/gc/stmtls.py
+++ b/rpython/memory/gc/stmtls.py
@@ -103,7 +103,7 @@
n = 10000 + len(StmGCTLS.nontranslated_dict)
tlsaddr = rffi.cast(llmemory.Address, n)
StmGCTLS.nontranslated_dict[n] = self
- self.stm_operations.set_tls(tlsaddr)
+ self.thread_descriptor = self.stm_operations.set_tls(tlsaddr)
def _unregister_with_C_code(self):
ll_assert(self.gc.get_tls() is self,
diff --git a/rpython/translator/stm/src_stm/et.h
b/rpython/translator/stm/src_stm/et.h
--- a/rpython/translator/stm/src_stm/et.h
+++ b/rpython/translator/stm/src_stm/et.h
@@ -105,12 +105,13 @@
extern void *pypy_g__stm_duplicate(void *);
extern void pypy_g__stm_enum_callback(void *, void *);
-void stm_set_tls(void *newtls);
+void *stm_set_tls(void *newtls);
void *stm_get_tls(void);
void stm_del_tls(void);
gcptr stm_tldict_lookup(gcptr); /* for tests only */
void stm_tldict_add(gcptr, gcptr); /* for tests only */
void stm_tldict_enum(void);
+void stm_tldict_enum_external(void *l_thread_descriptor);
long stm_in_transaction(void);
long stm_is_inevitable(void);
void stm_add_atomic(long delta);
diff --git a/rpython/translator/stm/src_stm/rpyintf.c
b/rpython/translator/stm/src_stm/rpyintf.c
--- a/rpython/translator/stm/src_stm/rpyintf.c
+++ b/rpython/translator/stm/src_stm/rpyintf.c
@@ -1,9 +1,10 @@
static __thread void *rpython_tls_object;
-void stm_set_tls(void *newtls)
+void *stm_set_tls(void *newtls)
{
rpython_tls_object = newtls;
+ return (void *)thread_descriptor;
}
void *stm_get_tls(void)
@@ -50,6 +51,20 @@
} G2L_LOOP_END;
}
+void stm_tldict_enum_external(void *l_thread_descriptor)
+{
+ struct tx_descriptor *d = (struct tx_descriptor *)l_thread_descriptor;
+ wlog_t *item;
+
+ G2L_LOOP_FORWARD(d->global_to_local, item)
+ {
+ gcptr R = item->addr;
+ gcptr L = item->val;
+ assert(L->h_revision == (revision_t)R);
+ pypy_g__stm_enum_external_callback(R, L);
+ } G2L_LOOP_END;
+}
+
long stm_in_transaction(void)
{
struct tx_descriptor *d = thread_descriptor;
diff --git a/rpython/translator/stm/stmgcintf.py
b/rpython/translator/stm/stmgcintf.py
--- a/rpython/translator/stm/stmgcintf.py
+++ b/rpython/translator/stm/stmgcintf.py
@@ -55,13 +55,15 @@
lltype.Void)
# for the GC: store and read a thread-local-storage field
- set_tls = smexternal('stm_set_tls', [llmemory.Address], lltype.Void)
+ set_tls = smexternal('stm_set_tls', [llmemory.Address], llmemory.Address)
get_tls = smexternal('stm_get_tls', [], llmemory.Address)
del_tls = smexternal('stm_del_tls', [], lltype.Void)
# calls FindRootsForLocalCollect() and invokes for each such root
# the callback set in CALLBACK_ENUM.
tldict_enum = smexternal('stm_tldict_enum', [], lltype.Void)
+ tldict_enum_external = smexternal('stm_tldict_enum_external',
+ [llmemory.Address], lltype.Void)
# sets the transaction length, after which should_break_transaction()
# returns True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit