[pypy-svn] r71476 - in pypy/branch/asmgcc-cantcollect/pypy: rpython/memory/gctransform translator/c/gcc translator/c/src
afa at codespeak.net
afa at codespeak.net
Thu Feb 25 00:05:55 CET 2010
Author: afa
Date: Thu Feb 25 00:05:54 2010
New Revision: 71476
Modified:
pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py
pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py
pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py
pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py
pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h
Log:
Add a marker after each call to a function that cannot collect,
and skip these calls in trackgcroot.
Tests pass on Windows, let's try with the buildbot
Modified: pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py (original)
+++ pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py Thu Feb 25 00:05:54 2010
@@ -40,6 +40,9 @@
def build_root_walker(self):
return AsmStackRootWalker(self)
+ def mark_call_cannotcollect(self, hop, name):
+ hop.genop("direct_call", [c_asm_nocollect, name])
+
def gct_direct_call(self, hop):
fnptr = hop.spaceop.args[0].value
try:
@@ -487,6 +490,12 @@
_nowrapper=True)
c_asm_gcroot = Constant(pypy_asm_gcroot, lltype.typeOf(pypy_asm_gcroot))
+pypy_asm_nocollect = rffi.llexternal('pypy_asm_gc_nocollect',
+ [rffi.CCHARP], lltype.Void,
+ sandboxsafe=True,
+ _nowrapper=True)
+c_asm_nocollect = Constant(pypy_asm_nocollect, lltype.typeOf(pypy_asm_nocollect))
+
QSORT_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address,
llmemory.Address], rffi.INT))
qsort = rffi.llexternal('qsort',
Modified: pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py Thu Feb 25 00:05:54 2010
@@ -577,6 +577,11 @@
self.pop_roots(hop, livevars)
else:
self.default(hop)
+ if hop.spaceop.opname == "direct_call":
+ self.mark_call_cannotcollect(hop, hop.spaceop.args[0])
+
+ def mark_call_cannotcollect(self, hop, name):
+ pass
gct_indirect_call = gct_direct_call
Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py (original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py Thu Feb 25 00:05:54 2010
@@ -164,8 +164,8 @@
return dict(zip(self.registers, self.registers))
class InsnCall(Insn):
- _args_ = ['lineno', 'gcroots']
- def __init__(self, lineno):
+ _args_ = ['lineno', 'name', 'gcroots']
+ def __init__(self, name, lineno):
# 'gcroots' is a dict built by side-effect during the call to
# FunctionGcRootTracker.trackgcroots(). Its meaning is as
# follows: the keys are the locations that contain gc roots
@@ -189,6 +189,7 @@
# %ebx from there in the prologue and epilogue).
self.gcroots = {}
self.lineno = lineno
+ self.name = name
def source_of(self, localvar, tag):
tag1 = self.gcroots.setdefault(localvar, tag)
Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py (original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Thu Feb 25 00:05:54 2010
@@ -38,6 +38,7 @@
self.filetag = filetag
# a "stack bottom" function is either main() or a callback from C code
self.is_stack_bottom = False
+ self.cannot_collect = {}
def computegcmaptable(self, verbose=0):
self.findlabels()
@@ -45,6 +46,7 @@
try:
if not self.list_call_insns():
return []
+ self.find_noncollecting_calls()
self.findframesize()
self.fixlocalvars()
self.trackgcroots()
@@ -65,6 +67,8 @@
for insn in self.list_call_insns():
if not hasattr(insn, 'framesize'):
continue # calls that never end up reaching a RET
+ if insn.name in self.cannot_collect:
+ continue
if self.is_stack_bottom:
retaddr = LOC_NOWHERE # end marker for asmgcroot.py
elif self.uses_frame_pointer:
@@ -81,10 +85,11 @@
if isinstance(localvar, LocalVar):
loc = localvar.getlocation(insn.framesize,
self.uses_frame_pointer)
- else:
- assert localvar in self.REG2LOC, "%s: %s" % (self.funcname,
- localvar)
+ elif localvar in self.REG2LOC:
loc = self.REG2LOC[localvar]
+ else:
+ assert False, "%s: %s" % (self.funcname,
+ localvar)
assert isinstance(loc, int)
if tag is None:
gcroots.append(loc)
@@ -116,6 +121,17 @@
assert label not in self.labels, "duplicate label: %s" % label
self.labels[label] = Label(label, lineno)
+ def find_noncollecting_calls(self):
+ for line in self.lines:
+ match = self.r_gcnocollect_marker.search(line)
+ if match:
+ name = match.group(1)
+ if name in ('pypy_g_walk_roots', 'pypy_asm_stackwalk'):
+ continue
+ if self.format in ('darwin', 'mingw32', 'msvc'):
+ name = '_' + name
+ self.cannot_collect[name] = True
+
def append_instruction(self, insn):
# Add the instruction to the list, and link it to the previous one.
previnsn = self.insns[-1]
@@ -641,7 +657,7 @@
if match is None:
assert self.r_unaryinsn_star.match(line) # indirect call
- return [InsnCall(self.currentlineno),
+ return [InsnCall('<indirect>', self.currentlineno),
InsnSetLocal(self.EAX)] # the result is there
target = match.group(1)
@@ -691,7 +707,7 @@
assert lineoffset in (1,2)
return [InsnStackAdjust(-4)]
- insns = [InsnCall(self.currentlineno),
+ insns = [InsnCall(target, self.currentlineno),
InsnSetLocal(self.EAX)] # the result is there
if self.format in ('mingw32', 'msvc'):
# handle __stdcall calling convention:
@@ -737,6 +753,7 @@
r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text|\t\.align|"+LABEL)
r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+LOCALVARFP+") [*]/")
+ r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+OPERAND+") [*]/")
r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/")
FUNCTIONS_NOT_RETURNING = {
@@ -813,6 +830,7 @@
r_gcroot_marker = re.compile(r"$1") # never matches
r_gcroot_marker_var = re.compile(r"DWORD PTR .+_constant_always_one_.+pypy_asm_gcroot")
+ r_gcnocollect_marker = re.compile(r"\spypy_asm_gc_nocollect\(("+OPERAND+")\);")
r_bottom_marker = re.compile(r"; .+\tpypy_asm_stack_bottom\(\);")
FUNCTIONS_NOT_RETURNING = {
Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h (original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h Thu Feb 25 00:05:54 2010
@@ -34,6 +34,9 @@
"0" (p), "m" (__gcnoreorderhack)); \
_r; })
+#define pypy_asm_gc_nocollect(f) asm volatile ("/* GC_NOCOLLECT " #f " */" \
+ : : )
+
#define pypy_asm_keepalive(v) asm volatile ("/* keepalive %0 */" : : \
"g" (v))
@@ -58,6 +61,8 @@
return _r1;
}
+#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */"
+
#define pypy_asm_keepalive(v) __asm { }
static __declspec(noinline) void pypy_asm_stack_bottom() { }
More information about the Pypy-commit
mailing list