[pypy-commit] pypy default: Tentatively fix all the problems we have with the main()
arigo
noreply at buildbot.pypy.org
Mon Jun 6 19:32:02 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r44761:017e187b2716
Date: 2011-06-06 18:33 +0200
http://bitbucket.org/pypy/pypy/changeset/017e187b2716/
Log: Tentatively fix all the problems we have with the main() function,
by not putting anything interesting in the main() function and
ignoring it during trackgcroot.
diff --git a/pypy/translator/c/gcc/instruction.py b/pypy/translator/c/gcc/instruction.py
--- a/pypy/translator/c/gcc/instruction.py
+++ b/pypy/translator/c/gcc/instruction.py
@@ -187,8 +187,8 @@
def requestgcroots(self, tracker):
# no need to track the value of these registers in the caller
- # function if we are the main(), or if we are flagged as a
- # "bottom" function (a callback from C code)
+ # function if we are flagged as a "bottom" function (a callback
+ # from C code, or pypy_main_function())
if tracker.is_stack_bottom:
return {}
else:
diff --git a/pypy/translator/c/gcc/test/elf/track10.s b/pypy/translator/c/gcc/test/elf/track10.s
--- a/pypy/translator/c/gcc/test/elf/track10.s
+++ b/pypy/translator/c/gcc/test/elf/track10.s
@@ -1,5 +1,5 @@
- .type main, @function
-main:
+ .type main1, @function
+main1:
pushl %ebx
call pypy_f
;; expected {4(%esp) | (%esp), %esi, %edi, %ebp | %ebx}
@@ -11,4 +11,4 @@
/* GCROOT %ebx */
popl %ebx
ret
- .size main, .-main
+ .size main1, .-main1
diff --git a/pypy/translator/c/gcc/test/elf/track4.s b/pypy/translator/c/gcc/test/elf/track4.s
deleted file mode 100644
--- a/pypy/translator/c/gcc/test/elf/track4.s
+++ /dev/null
@@ -1,52 +0,0 @@
- .type main, @function
-main:
- ;; this is an artificial example showing what kind of code gcc
- ;; can produce for main()
- pushl %ebp
- movl %eax, $globalptr1
- movl %esp, %ebp
- pushl %edi
- subl $8, %esp
- andl $-16, %esp
- movl %ebx, -8(%ebp)
- movl 8(%ebp), %edi
- call foobar
- ;; expected {4(%ebp) | -8(%ebp), %esi, -4(%ebp), (%ebp) | %edi}
-.L1:
- cmpl $0, %eax
- je .L3
-.L2:
- ;; inlined function here with -fomit-frame-pointer
- movl %eax, -12(%ebp)
- movl %edi, %edx
- subl $16, %esp
- movl %eax, (%esp)
- movl $42, %edi
- movl %edx, 4(%esp)
- movl %esi, %ebx
- movl $nonsense, %esi
- call foobar
- ;; expected {4(%ebp) | -8(%ebp), %ebx, -4(%ebp), (%ebp) | 4(%esp), -12(%ebp)}
- addl %edi, %eax
- movl 4(%esp), %eax
- movl %ebx, %esi
- addl $16, %esp
- movl %eax, %edi
- movl -12(%ebp), %eax
-#APP
- /* GCROOT %eax */
-#NO_APP
- ;; end of inlined function
-.L3:
- call foobar
- ;; expected {4(%ebp) | -8(%ebp), %esi, -4(%ebp), (%ebp) | %edi}
-#APP
- /* GCROOT %edi */
-#NO_APP
- movl -8(%ebp), %ebx
- movl -4(%ebp), %edi
- movl %ebp, %esp
- popl %ebp
- ret
-
- .size main, .-main
diff --git a/pypy/translator/c/gcc/test/elf/track6.s b/pypy/translator/c/gcc/test/elf/track6.s
deleted file mode 100644
--- a/pypy/translator/c/gcc/test/elf/track6.s
+++ /dev/null
@@ -1,26 +0,0 @@
- .type main, @function
-main:
- ;; a minimal example showing what kind of code gcc
- ;; can produce for main(): some local variable accesses
- ;; are relative to %ebp, while others are relative to
- ;; %esp, and the difference %ebp-%esp is not constant
- ;; because of the 'andl' to align the stack
- pushl %ebp
- movl %esp, %ebp
- subl $8, %esp
- andl $-16, %esp
- movl $globalptr1, -4(%ebp)
- movl $globalptr2, (%esp)
- pushl $0
- call foobar
- ;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | 4(%esp), -4(%ebp)}
- popl %eax
-#APP
- /* GCROOT -4(%ebp) */
- /* GCROOT (%esp) */
-#NO_APP
- movl %ebp, %esp
- popl %ebp
- ret
-
- .size main, .-main
diff --git a/pypy/translator/c/gcc/test/elf/track7.s b/pypy/translator/c/gcc/test/elf/track7.s
--- a/pypy/translator/c/gcc/test/elf/track7.s
+++ b/pypy/translator/c/gcc/test/elf/track7.s
@@ -1,5 +1,5 @@
- .type main, @function
-main:
+ .type main1, @function
+main1:
;; cmovCOND tests.
pushl %ebx
movl 12(%esp), %ebx
@@ -16,4 +16,4 @@
popl %ebx
ret
- .size main, .-main
+ .size main1, .-main1
diff --git a/pypy/translator/c/gcc/test/msvc/track6.s b/pypy/translator/c/gcc/test/msvc/track6.s
deleted file mode 100644
--- a/pypy/translator/c/gcc/test/msvc/track6.s
+++ /dev/null
@@ -1,15 +0,0 @@
-_TEXT SEGMENT
-_pypy_g_foo PROC ; COMDAT
-
- push ebp
- mov ebp, esp
- and esp, -64
- sub esp, 12
- push esi
- call _pypy_g_something_else
- ;; expected {4(%ebp) | %ebx, (%esp), %edi, (%ebp) | }
- pop esi
- mov esp, ebp
- pop ebp
- ret 0
-_pypy_g_foo ENDP
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -39,10 +39,15 @@
self.uses_frame_pointer = False
self.r_localvar = self.r_localvarnofp
self.filetag = filetag
- # a "stack bottom" function is either main() or a callback from C code
+ # a "stack bottom" function is either pypy_main_function() or a
+ # callback from C code. In both cases they are identified by
+ # the presence of pypy_asm_stack_bottom().
self.is_stack_bottom = False
def computegcmaptable(self, verbose=0):
+ if self.funcname in ['main', '_main']:
+ return [] # don't analyze main(), its prologue may contain
+ # strange instructions
self.findlabels()
self.parse_instructions()
try:
@@ -226,7 +231,7 @@
# in the frame at this point. This doesn't count the return address
# which is the word immediately following the frame in memory.
# The 'framesize' is set to an odd value if it is only an estimate
- # (see visit_andl()).
+ # (see InsnCannotFollowEsp).
def walker(insn, size_delta):
check = deltas.setdefault(insn, size_delta)
@@ -521,10 +526,8 @@
target = match.group("target")
if target == self.ESP:
# only for andl $-16, %esp used to align the stack in main().
- # The exact amount of adjutment is not known yet, so we use
- # an odd-valued estimate to make sure the real value is not used
- # elsewhere by the FunctionGcRootTracker.
- return InsnCannotFollowEsp()
+ # main() should not be seen at all.
+ raise AssertionError("instruction unexpected outside of main()")
else:
return self.binary_insn(line)
@@ -1323,12 +1326,11 @@
self.verbose = verbose
self.shuffle = shuffle
self.gcmaptable = []
- self.seen_main = False
- def process(self, iterlines, newfile, entrypoint='main', filename='?'):
+ def process(self, iterlines, newfile, filename='?'):
for in_function, lines in self.find_functions(iterlines):
if in_function:
- tracker = self.process_function(lines, entrypoint, filename)
+ tracker = self.process_function(lines, filename)
lines = tracker.lines
self.write_newfile(newfile, lines, filename.split('.')[0])
if self.verbose == 1:
@@ -1337,11 +1339,9 @@
def write_newfile(self, newfile, lines, grist):
newfile.writelines(lines)
- def process_function(self, lines, entrypoint, filename):
+ def process_function(self, lines, filename):
tracker = self.FunctionGcRootTracker(
lines, filetag=getidentifier(filename))
- is_main = tracker.funcname == entrypoint
- tracker.is_stack_bottom = is_main
if self.verbose == 1:
sys.stderr.write('.')
elif self.verbose > 1:
@@ -1356,7 +1356,6 @@
self.gcmaptable[:0] = table
else:
self.gcmaptable.extend(table)
- self.seen_main |= is_main
return tracker
class ElfAssemblerParser(AssemblerParser):
@@ -1432,11 +1431,6 @@
if functionlines:
yield in_function, functionlines
- def process_function(self, lines, entrypoint, filename):
- entrypoint = '_' + entrypoint
- return super(DarwinAssemblerParser, self).process_function(
- lines, entrypoint, filename)
-
class DarwinAssemblerParser64(DarwinAssemblerParser):
format = "darwin64"
FunctionGcRootTracker = DarwinFunctionGcRootTracker64
@@ -1494,11 +1488,6 @@
"missed the end of the previous function")
yield False, functionlines
- def process_function(self, lines, entrypoint, filename):
- entrypoint = '_' + entrypoint
- return super(MsvcAssemblerParser, self).process_function(
- lines, entrypoint, filename)
-
def write_newfile(self, newfile, lines, grist):
newlines = []
for line in lines:
@@ -1560,24 +1549,21 @@
self.shuffle = shuffle # to debug the sorting logic in asmgcroot.py
self.format = format
self.gcmaptable = []
- self.seen_main = False
def dump_raw_table(self, output):
- print >> output, "seen_main = %d" % (self.seen_main,)
+ print 'raw table'
for entry in self.gcmaptable:
print >> output, entry
def reload_raw_table(self, input):
firstline = input.readline()
- assert firstline.startswith("seen_main = ")
- self.seen_main |= bool(int(firstline[len("seen_main = "):].strip()))
+ assert firstline == 'raw table\n'
for line in input:
entry = eval(line)
assert type(entry) is tuple
self.gcmaptable.append(entry)
def dump(self, output):
- assert self.seen_main
def _globalname(name, disp=""):
return tracker_cls.function_names_prefix + name
@@ -1835,11 +1821,11 @@
""".replace("__gccallshapes", _globalname("__gccallshapes"))
output.writelines(shapelines)
- def process(self, iterlines, newfile, entrypoint='main', filename='?'):
+ def process(self, iterlines, newfile, filename='?'):
parser = PARSERS[format](verbose=self.verbose, shuffle=self.shuffle)
for in_function, lines in parser.find_functions(iterlines):
if in_function:
- tracker = parser.process_function(lines, entrypoint, filename)
+ tracker = parser.process_function(lines, filename)
lines = tracker.lines
parser.write_newfile(newfile, lines, filename.split('.')[0])
if self.verbose == 1:
@@ -1848,7 +1834,6 @@
self.gcmaptable[:0] = parser.gcmaptable
else:
self.gcmaptable.extend(parser.gcmaptable)
- self.seen_main |= parser.seen_main
class UnrecognizedOperation(Exception):
@@ -1915,7 +1900,6 @@
format = 'elf64'
else:
format = 'elf'
- entrypoint = 'main'
while len(sys.argv) > 1:
if sys.argv[1] == '-v':
del sys.argv[1]
@@ -1929,9 +1913,9 @@
elif sys.argv[1].startswith('-f'):
format = sys.argv[1][2:]
del sys.argv[1]
- elif sys.argv[1].startswith('-m'):
- entrypoint = sys.argv[1][2:]
- del sys.argv[1]
+ elif sys.argv[1].startswith('-'):
+ print >> sys.stderr, "unrecognized option:", sys.argv[1]
+ sys.exit(1)
else:
break
tracker = GcRootTracker(verbose=verbose, shuffle=shuffle, format=format)
@@ -1940,7 +1924,7 @@
firstline = f.readline()
f.seek(0)
assert firstline, "file %r is empty!" % (fn,)
- if firstline.startswith('seen_main = '):
+ if firstline == 'raw table\n':
tracker.reload_raw_table(f)
f.close()
else:
@@ -1948,7 +1932,7 @@
lblfn = fn[:-2] + '.lbl.s'
g = open(lblfn, 'w')
try:
- tracker.process(f, g, entrypoint=entrypoint, filename=fn)
+ tracker.process(f, g, filename=fn)
except:
g.close()
os.unlink(lblfn)
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
@@ -602,7 +602,7 @@
'cmd /c $(MASM) /nologo /Cx /Cp /Zm /coff /Fo$@ /c $< $(INCLUDEDIRS)')
mk.rule('.c.gcmap', '',
['$(CC) /nologo $(ASM_CFLAGS) /c /FAs /Fa$*.s $< $(INCLUDEDIRS)',
- 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -fmsvc -m$(PYPY_MAIN_FUNCTION) -t $*.s > $@']
+ 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -fmsvc -t $*.s > $@']
)
mk.rule('gcmaptable.c', '$(GCMAPFILES)',
'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -fmsvc $(GCMAPFILES) > $@')
@@ -613,7 +613,7 @@
mk.rule('%.lbl.s %.gcmap', '%.s',
[python +
'$(PYPYDIR)/translator/c/gcc/trackgcroot.py '
- '-m$(PYPY_MAIN_FUNCTION) -t $< > $*.gctmp',
+ '-t $< > $*.gctmp',
'mv $*.gctmp $*.gcmap'])
mk.rule('gcmaptable.s', '$(GCMAPFILES)',
[python +
diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h
--- a/pypy/translator/c/src/main.h
+++ b/pypy/translator/c/src/main.h
@@ -23,12 +23,19 @@
#include "src/winstuff.c"
#endif
-int PYPY_MAIN_FUNCTION(int argc, char *argv[])
+#ifdef __GNUC__
+/* Hack to prevent this function from being inlined. Helps asmgcc
+ because the main() function has often a different prologue/epilogue. */
+int pypy_main_function(int argc, char *argv[]) __attribute__((__noinline__));
+#endif
+
+int pypy_main_function(int argc, char *argv[])
{
char *errmsg;
int i, exitcode;
RPyListOfString *list;
+ pypy_asm_stack_bottom();
instrument_setup();
if (sizeof(void*) != SIZEOF_LONG) {
@@ -74,4 +81,9 @@
abort();
}
+int PYPY_MAIN_FUNCTION(int argc, char *argv[])
+{
+ return pypy_main_function(argc, argv);
+}
+
#endif /* PYPY_NOT_MAIN_FILE */
More information about the pypy-commit
mailing list