[pypy-commit] pypy stm-gc: In-progress: hack at all files until targetdemo.py at least compiles.
arigo
noreply at buildbot.pypy.org
Thu Feb 9 16:19:24 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52301:c14db797e8a3
Date: 2012-02-09 16:17 +0100
http://bitbucket.org/pypy/pypy/changeset/c14db797e8a3/
Log: In-progress: hack at all files until targetdemo.py at least
compiles. Doesn't run at all so far.
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -75,7 +75,7 @@
"markcompact": [("translation.gctransformer", "framework")],
"minimark": [("translation.gctransformer", "framework")],
"stmgc": [("translation.gctransformer", "framework"),
- ("translation.gcrootfinder", "none")], # XXX
+ ("translation.gcrootfinder", "stm")],
},
cmdline="--gc"),
ChoiceOption("gctransformer", "GC transformer that is used - internal",
@@ -93,7 +93,7 @@
default=IS_64_BITS, cmdline="--gcremovetypeptr"),
ChoiceOption("gcrootfinder",
"Strategy for finding GC Roots (framework GCs only)",
- ["n/a", "shadowstack", "asmgcc", "none"],
+ ["n/a", "shadowstack", "asmgcc", "stm"],
"shadowstack",
cmdline="--gcrootfinder",
requires={
diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py
--- a/pypy/objspace/flow/model.py
+++ b/pypy/objspace/flow/model.py
@@ -166,7 +166,7 @@
def show(self):
from pypy.translator.tool.graphpage import try_show
- try_show(self)
+ return try_show(self)
class Block(object):
@@ -241,7 +241,7 @@
def show(self):
from pypy.translator.tool.graphpage import try_show
- try_show(self)
+ return try_show(self)
class Variable(object):
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -1,6 +1,7 @@
import thread
from pypy.rlib.objectmodel import specialize, we_are_translated, keepalive_until_here
from pypy.rpython.lltypesystem import rffi, lltype, rclass
+from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import (cast_base_ptr_to_instance,
cast_instance_to_base_ptr,
llhelper)
@@ -45,12 +46,12 @@
def descriptor_init():
if not we_are_translated(): _global_lock.acquire()
- _rffi_stm.stm_descriptor_init()
+ llop.stm_descriptor_init(lltype.Void)
if not we_are_translated(): _global_lock.release()
def descriptor_done():
if not we_are_translated(): _global_lock.acquire()
- _rffi_stm.stm_descriptor_done()
+ llop.stm_descriptor_done(lltype.Void)
if not we_are_translated(): _global_lock.release()
def debug_get_state():
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -396,12 +396,11 @@
# to keep them as operations until the genc stage)
'stm_getfield': LLOp(sideeffects=False, canrun=True),
- 'stm_setfield': LLOp(),
'stm_getarrayitem': LLOp(sideeffects=False, canrun=True),
- 'stm_setarrayitem': LLOp(),
'stm_getinteriorfield': LLOp(sideeffects=False, canrun=True),
- 'stm_setinteriorfield': LLOp(),
'stm_become_inevitable':LLOp(),
+ 'stm_descriptor_init': LLOp(),
+ 'stm_descriptor_done': LLOp(),
# __________ address operations __________
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
@@ -77,8 +77,8 @@
return self.get_size(obj)
self._getsize_fn = _get_size
#
- for size, TYPE in PRIMITIVE_SIZES.items():
- self.declare_reader(size, TYPE)
+ ##for size, TYPE in PRIMITIVE_SIZES.items():
+ ## self.declare_reader(size, TYPE)
self.declare_write_barrier()
GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
@@ -121,6 +121,9 @@
tls.malloc_flags = 0
return tls
+ def _setup_secondary_thread(self):
+ self.setup_thread(False)
+
@staticmethod
def reset_nursery(tls):
"""Clear and forget all locally allocated objects."""
@@ -222,23 +225,25 @@
# ----------
- def declare_reader(self, size, TYPE):
- # Reading functions. Defined here to avoid the extra burden of
- # passing 'self' explicitly.
- assert rffi.sizeof(TYPE) == size
- PTYPE = rffi.CArrayPtr(TYPE)
- stm_read_int = getattr(self.stm_operations, 'stm_read_int%d' % size)
- #
- @always_inline
- def reader(obj, offset):
- if self.header(obj).tid & GCFLAG_GLOBAL == 0:
- adr = rffi.cast(PTYPE, obj + offset)
- return adr[0] # local obj: read directly
- else:
- return stm_read_int(obj, offset) # else: call a helper
- setattr(self, 'read_int%d' % size, reader)
- #
- # the following logic was moved to et.c to avoid a double call
+## TURNED OFF, maybe temporarily: the following logic is now entirely
+## done by C macros and functions.
+##
+## def declare_reader(self, size, TYPE):
+## # Reading functions. Defined here to avoid the extra burden of
+## # passing 'self' explicitly.
+## assert rffi.sizeof(TYPE) == size
+## PTYPE = rffi.CArrayPtr(TYPE)
+## stm_read_int = getattr(self.stm_operations, 'stm_read_int%d' % size)
+## #
+## @always_inline
+## def reader(obj, offset):
+## if self.header(obj).tid & GCFLAG_GLOBAL == 0:
+## adr = rffi.cast(PTYPE, obj + offset)
+## return adr[0] # local obj: read directly
+## else:
+## return stm_read_int(obj, offset) # else: call a helper
+## setattr(self, 'read_int%d' % size, reader)
+## #
## @dont_inline
## def _read_word_global(obj, offset):
## hdr = self.header(obj)
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
@@ -138,7 +138,6 @@
def __init__(self, translator):
from pypy.rpython.memory.gc.base import choose_gc_from_config
from pypy.rpython.memory.gc.base import ARRAY_TYPEID_MAP
- from pypy.rpython.memory.gc import inspector
super(FrameworkGCTransformer, self).__init__(translator, inline=True)
if hasattr(self, 'GC_PARAMS'):
@@ -251,7 +250,47 @@
classdef = bk.getuniqueclassdef(GCClass)
s_gc = annmodel.SomeInstance(classdef)
+
+ self._declare_functions(GCClass, getfn, s_gc, s_typeid16)
+
+ # thread support
+ if translator.config.translation.continuation:
+ root_walker.need_stacklet_support(self, getfn)
+ if translator.config.translation.thread:
+ root_walker.need_thread_support(self, getfn)
+
+ self.layoutbuilder.encode_type_shapes_now()
+
+ annhelper.finish() # at this point, annotate all mix-level helpers
+ annhelper.backend_optimize()
+
+ self.collect_analyzer = CollectAnalyzer(self.translator)
+ self.collect_analyzer.analyze_all()
+
+ s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass)
+ r_gc = self.translator.rtyper.getrepr(s_gc)
+ self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
+ s_gc_data = self.translator.annotator.bookkeeper.valueoftype(
+ gctypelayout.GCData)
+ r_gc_data = self.translator.rtyper.getrepr(s_gc_data)
+ self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata)
+ self.malloc_zero_filled = GCClass.malloc_zero_filled
+
+ HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
+
+ size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
+ vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
+ self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo)
+ tig = self.layoutbuilder.type_info_group._as_ptr()
+ self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig)
+ sko = llmemory.sizeof(gcdata.TYPE_INFO)
+ self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko)
+
+
+ def _declare_functions(self, GCClass, getfn, s_gc, s_typeid16):
s_gcref = annmodel.SomePtr(llmemory.GCREF)
+ gcdata = self.gcdata
+ translator = self.translator
malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func
self.malloc_fixedsize_clear_ptr = getfn(
@@ -412,6 +451,7 @@
else:
self.id_ptr = None
+ from pypy.rpython.memory.gc import inspector
self.get_rpy_roots_ptr = getfn(inspector.get_rpy_roots,
[s_gc],
rgc.s_list_of_gcrefs(),
@@ -488,39 +528,6 @@
[s_gc, annmodel.SomeInteger()],
annmodel.SomeInteger())
- # thread support
- if translator.config.translation.continuation:
- root_walker.need_stacklet_support(self, getfn)
- if translator.config.translation.thread:
- root_walker.need_thread_support(self, getfn)
-
- self.layoutbuilder.encode_type_shapes_now()
-
- annhelper.finish() # at this point, annotate all mix-level helpers
- annhelper.backend_optimize()
-
- self.collect_analyzer = CollectAnalyzer(self.translator)
- self.collect_analyzer.analyze_all()
-
- s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass)
- r_gc = self.translator.rtyper.getrepr(s_gc)
- self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
- s_gc_data = self.translator.annotator.bookkeeper.valueoftype(
- gctypelayout.GCData)
- r_gc_data = self.translator.rtyper.getrepr(s_gc_data)
- self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata)
- self.malloc_zero_filled = GCClass.malloc_zero_filled
-
- HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
-
- size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
- vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
- self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo)
- tig = self.layoutbuilder.type_info_group._as_ptr()
- self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig)
- sko = llmemory.sizeof(gcdata.TYPE_INFO)
- self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko)
-
def build_root_walker(self):
from pypy.rpython.memory.gctransform import shadowstack
return shadowstack.ShadowStackRootWalker(self)
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -0,0 +1,38 @@
+from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer
+from pypy.rpython.memory.gctransform.framework import BaseRootWalker
+from pypy.annotation import model as annmodel
+
+
+class StmFrameworkGCTransformer(FrameworkGCTransformer):
+
+ def _declare_functions(self, GCClass, getfn, s_gc, *args):
+ super(StmFrameworkGCTransformer, self)._declare_functions(
+ GCClass, getfn, s_gc, *args)
+ self.setup_secondary_thread_ptr = getfn(
+ GCClass._setup_secondary_thread.im_func,
+ [s_gc], annmodel.s_None)
+ self.teardown_thread_ptr = getfn(
+ GCClass.teardown_thread.im_func,
+ [s_gc], annmodel.s_None)
+
+ def push_roots(self, hop, keep_current_args=False):
+ pass
+
+ def pop_roots(self, hop, livevars):
+ pass
+
+ def build_root_walker(self):
+ return StmStackRootWalker(self)
+
+ def gct_stm_descriptor_init(self, hop):
+ hop.genop("direct_call", [self.setup_secondary_thread_ptr,
+ self.c_const_gc])
+
+ def gct_stm_descriptor_done(self, hop):
+ hop.genop("direct_call", [self.teardown_thread_ptr, self.c_const_gc])
+
+
+class StmStackRootWalker(BaseRootWalker):
+
+ def walk_stack_roots(self, collect_stack_root):
+ raise NotImplementedError
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -6,7 +6,7 @@
typeOf, Ptr, ContainerType, RttiStruct, \
RuntimeTypeInfo, getRuntimeTypeInfo, top_container
from pypy.rpython.memory.gctransform import \
- refcounting, boehm, framework, asmgcroot
+ refcounting, boehm, framework, asmgcroot, stmframework
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -404,6 +404,9 @@
def OP_GC_STACK_BOTTOM(self, funcgen, op):
return 'pypy_asm_stack_bottom();'
+class StmFrameworkGcPolicy(FrameworkGcPolicy):
+ transformerclass = stmframework.StmFrameworkGCTransformer
+
name_to_gcpolicy = {
'boehm': BoehmGcPolicy,
@@ -411,6 +414,5 @@
'none': NoneGcPolicy,
'framework': FrameworkGcPolicy,
'framework+asmgcroot': AsmGcRootFrameworkGcPolicy,
+ 'framework+stm': StmFrameworkGcPolicy,
}
-
-
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -199,8 +199,10 @@
def get_gcpolicyclass(self):
if self.gcpolicy is None:
name = self.config.translation.gctransformer
- if self.config.translation.gcrootfinder == "asmgcc":
- name = "%s+asmgcroot" % (name,)
+ extended_name = "%s+%s" % (
+ name, self.config.translation.gcrootfinder)
+ if extended_name in gc.name_to_gcpolicy:
+ name = extended_name
return gc.name_to_gcpolicy[name]
return self.gcpolicy
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -4,7 +4,7 @@
from pypy.translator.stm.llstm import size_of_voidp
-def _stm_generic_get(funcgen, op, expr, simple_struct=False):
+def _stm_generic_get(funcgen, op, (expr_type, expr_ptr, expr_field)):
T = funcgen.lltypemap(op.result)
resulttypename = funcgen.db.gettype(T)
cresulttypename = cdecl(resulttypename, '')
@@ -12,117 +12,50 @@
#
assert T is not lltype.Void # XXX
fieldsize = rffi.sizeof(T)
- if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
- assert 1 # xxx assert somehow that the field is aligned
- if T == lltype.Float:
- funcname = 'stm_read_double'
- elif T == lltype.SingleFloat:
- funcname = 'stm_read_float'
- elif fieldsize == size_of_voidp:
- funcname = 'stm_read_word'
- elif fieldsize == 8: # 32-bit only: read a 64-bit field
- funcname = 'stm_read_doubleword'
- else:
- raise NotImplementedError(fieldsize)
- return '%s = (%s)%s((long*)&%s);' % (
- newvalue, cresulttypename, funcname, expr)
+ assert fieldsize in (1, 2, 4, 8)
+ if T == lltype.Float:
+ assert fieldsize == 8
+ fieldsize = '8f'
+ elif T == lltype.SingleFloat:
+ assert fieldsize == 4
+ fieldsize = '4f'
+ if expr_type is not None: # optimization for the common case
+ return '%s = RPY_STM_FIELD(%s, %s, %s, %s, %s);' % (
+ newvalue, cresulttypename, fieldsize,
+ expr_type, expr_ptr, expr_field)
else:
- assert fieldsize in (1, 2, 4)
- if simple_struct:
- # assume that the object is aligned, and any possible misalignment
- # comes from the field offset, so that it can be resolved at
- # compile-time (by using C macros)
- STRUCT = funcgen.lltypemap(op.args[0]).TO
- structdef = funcgen.db.gettypedefnode(STRUCT)
- basename = funcgen.expr(op.args[0])
- fieldname = op.args[1].value
- trailing = ''
- if T == lltype.Bool:
- trailing = ' & 1' # needed in this case, otherwise casting
- # a several-bytes value to bool_t would
- # take into account all the several bytes
- return '%s = (%s)(stm_fx_read_partial(%s, offsetof(%s, %s))%s);'% (
- newvalue, cresulttypename, basename,
- cdecl(funcgen.db.gettype(STRUCT), ''),
- structdef.c_struct_field_name(fieldname),
- trailing)
- #
- else:
- return '%s = (%s)stm_read_partial_%d(&%s);' % (
- newvalue, cresulttypename, fieldsize, expr)
-
-def _stm_generic_set(funcgen, op, targetexpr, T):
- basename = funcgen.expr(op.args[0])
- newvalue = funcgen.expr(op.args[-1], special_case_void=False)
- #
- assert T is not lltype.Void # XXX
- fieldsize = rffi.sizeof(T)
- if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
- assert 1 # xxx assert somehow that the field is aligned
- if T == lltype.Float:
- funcname = 'stm_write_double'
- newtype = 'double'
- elif T == lltype.SingleFloat:
- funcname = 'stm_write_float'
- newtype = 'float'
- elif fieldsize == size_of_voidp:
- funcname = 'stm_write_word'
- newtype = 'long'
- elif fieldsize == 8: # 32-bit only: read a 64-bit field
- funcname = 'stm_write_doubleword'
- newtype = 'long long'
- else:
- raise NotImplementedError(fieldsize)
- return '%s((long*)&%s, (%s)%s);' % (
- funcname, targetexpr, newtype, newvalue)
- else:
- assert fieldsize in (1, 2, 4)
- return ('stm_write_partial_%d(&%s, (unsigned long)%s);' % (
- fieldsize, targetexpr, newvalue))
+ return '%s = RPY_STM_ARRAY(%s, %s, %s, %s);' % (
+ newvalue, cresulttypename, fieldsize,
+ expr_ptr, expr_field)
def field_expr(funcgen, args):
STRUCT = funcgen.lltypemap(args[0]).TO
structdef = funcgen.db.gettypedefnode(STRUCT)
- baseexpr_is_const = isinstance(args[0], Constant)
- return structdef.ptr_access_expr(funcgen.expr(args[0]),
- args[1].value,
- baseexpr_is_const)
+ fldname = structdef.c_struct_field_name(args[1].value)
+ ptr = funcgen.expr(args[0])
+ return ('%s %s' % (structdef.typetag, structdef.name), ptr, fldname)
def stm_getfield(funcgen, op):
- expr = field_expr(funcgen, op.args)
- return _stm_generic_get(funcgen, op, expr, simple_struct=True)
-
-def stm_setfield(funcgen, op):
- expr = field_expr(funcgen, op.args)
- T = op.args[2].concretetype
- return _stm_generic_set(funcgen, op, expr, T)
+ access_info = field_expr(funcgen, op.args)
+ return _stm_generic_get(funcgen, op, access_info)
def array_expr(funcgen, args):
ARRAY = funcgen.lltypemap(args[0]).TO
ptr = funcgen.expr(args[0])
index = funcgen.expr(args[1])
arraydef = funcgen.db.gettypedefnode(ARRAY)
- return arraydef.itemindex_access_expr(ptr, index)
+ return (None, ptr, arraydef.itemindex_access_expr(ptr, index))
def stm_getarrayitem(funcgen, op):
- expr = array_expr(funcgen, op.args)
- return _stm_generic_get(funcgen, op, expr)
-
-def stm_setarrayitem(funcgen, op):
- expr = array_expr(funcgen, op.args)
- T = op.args[2].concretetype
- return _stm_generic_set(funcgen, op, expr, T)
+ access_info = array_expr(funcgen, op.args)
+ return _stm_generic_get(funcgen, op, access_info)
def stm_getinteriorfield(funcgen, op):
+ xxx
expr = funcgen.interior_expr(op.args)
return _stm_generic_get(funcgen, op, expr)
-def stm_setinteriorfield(funcgen, op):
- expr = funcgen.interior_expr(op.args[:-1])
- T = op.args[-1].concretetype
- return _stm_generic_set(funcgen, op, expr, T)
-
def stm_become_inevitable(funcgen, op):
info = op.args[0].value
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -38,19 +38,13 @@
/************************************************************/
/* This is the same as the object header structure HDR
- * declared in stmgc.py, and the same two flags */
+ * declared in stmgc.py */
typedef struct {
long tid;
long version;
} orec_t;
-enum {
- first_gcflag = 1L << (PYPY_LONG_BIT / 2),
- GCFLAG_GLOBAL = first_gcflag << 0,
- GCFLAG_WAS_COPIED = first_gcflag << 1
-};
-
/************************************************************/
#define IS_LOCKED(num) ((num) < 0)
@@ -681,7 +675,6 @@
return result;
}
-#if 0
void stm_try_inevitable(STM_CCHARP1(why))
{
/* when a transaction is inevitable, its start_time is equal to
@@ -689,7 +682,7 @@
by another thread. We set the lowest bit in global_timestamp
to 1. */
struct tx_descriptor *d = thread_descriptor;
- if (!d->transaction_active)
+ if (is_main_thread(d))
return;
#ifdef RPY_STM_ASSERT
@@ -697,17 +690,16 @@
if (PYPY_HAVE_DEBUG_PRINTS)
{
fprintf(PYPY_DEBUG_FILE, "%s%s\n", why,
- (!d->transaction_active) ? " (inactive)" :
- is_inevitable(d) ? " (already inevitable)" : "");
+ is_inevitable(d) ? "" : " <====");
}
#endif
- if (is_inevitable_or_inactive(d))
+ if (is_inevitable(d))
{
#ifdef RPY_STM_ASSERT
PYPY_DEBUG_STOP("stm-inevitable");
#endif
- return; /* I am already inevitable, or not in a transaction at all */
+ return; /* I am already inevitable */
}
while (1)
@@ -738,7 +730,6 @@
PYPY_DEBUG_STOP("stm-inevitable");
#endif
}
-#endif
void stm_abort_and_retry(void)
{
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -22,11 +22,12 @@
void stm_tldict_add(void *, void *);
void stm_tlidct_enum(void(*)(void*, void*));
-long stm_read_word(void *, long);
+char stm_read_int1(void *, long);
+short stm_read_int2(void *, long);
+int stm_read_int4(void *, long);
+long long stm_read_int8(void *, long);
-#if 0
-
#ifdef RPY_STM_ASSERT
# define STM_CCHARP1(arg) char* arg
# define STM_EXPLAIN1(info) info
@@ -37,8 +38,6 @@
void* stm_perform_transaction(void*(*)(void*, long), void*);
-long stm_read_word(long* addr);
-void stm_write_word(long* addr, long val);
void stm_try_inevitable(STM_CCHARP1(why));
void stm_abort_and_retry(void);
long stm_debug_get_state(void); /* -1: descriptor_init() was not called
@@ -48,33 +47,27 @@
long stm_thread_id(void); /* returns a unique thread id,
or 0 if descriptor_init() was not called */
-// XXX little-endian only!
-/* this macro is used if 'base' is a word-aligned pointer and 'offset'
- is a compile-time constant */
-#define stm_fx_read_partial(base, offset) \
- (stm_read_word( \
- (long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1)))) \
- >> (8 * ((offset) & (sizeof(void*)-1))))
-unsigned char stm_read_partial_1(void *addr);
-unsigned short stm_read_partial_2(void *addr);
-void stm_write_partial_1(void *addr, unsigned char nval);
-void stm_write_partial_2(void *addr, unsigned short nval);
-#if PYPY_LONG_BIT == 64
-unsigned int stm_read_partial_4(void *addr);
-void stm_write_partial_4(void *addr, unsigned int nval);
-#endif
+/************************************************************/
-double stm_read_double(long *addr);
-void stm_write_double(long *addr, double val);
-float stm_read_float(long *addr);
-void stm_write_float(long *addr, float val);
-#if PYPY_LONG_BIT == 32
-long long stm_read_doubleword(long *addr);
-void stm_write_doubleword(long *addr, long long val);
-#endif
+/* These are the same two flags as defined in stmgc.py */
-#endif /* 0 */
+enum {
+ first_gcflag = 1L << (PYPY_LONG_BIT / 2),
+ GCFLAG_GLOBAL = first_gcflag << 0,
+ GCFLAG_WAS_COPIED = first_gcflag << 1
+};
+
+
+#define RPY_STM_ARRAY(T, size, ptr, field) \
+ _RPY_STM(T, size, ptr, ((char*)&field)-((char*)ptr), field)
+
+#define RPY_STM_FIELD(T, size, STRUCT, ptr, field) \
+ _RPY_STM(T, size, ptr, offsetof(STRUCT, field), ptr->field)
+
+#define _RPY_STM(T, size, ptr, offset, field) \
+ (*(long*)ptr & GCFLAG_GLOBAL ? field : \
+ (T)stm_read_int##size(ptr, offset))
#endif /* _ET_H */
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -141,11 +141,9 @@
elif (STRUCT._immutable_field(op.args[1].value) or
'stm_access_directly' in STRUCT._hints):
op1 = op
- elif STRUCT._gckind == 'raw':
+ else:
turn_inevitable(newoperations, "setfield-raw")
op1 = op
- else:
- op1 = SpaceOperation('stm_setfield', op.args, op.result)
newoperations.append(op1)
def stt_getarrayitem(self, newoperations, op):
@@ -171,11 +169,9 @@
op1 = op
#elif op.args[0] in self.access_directly:
# op1 = op
- elif ARRAY._gckind == 'raw':
+ else:
turn_inevitable(newoperations, "setarrayitem-raw")
op1 = op
- else:
- op1 = SpaceOperation('stm_setarrayitem', op.args, op.result)
newoperations.append(op1)
def stt_getinteriorfield(self, newoperations, op):
diff --git a/pypy/translator/tool/graphpage.py b/pypy/translator/tool/graphpage.py
--- a/pypy/translator/tool/graphpage.py
+++ b/pypy/translator/tool/graphpage.py
@@ -439,7 +439,7 @@
for y in gc.get_referrers(x):
if isinstance(y, FunctionGraph):
y.show()
- return
+ return y
elif isinstance(y, Link):
block = y.prevblock
if block not in seen:
More information about the pypy-commit
mailing list