Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r44762:5904225493ed Date: 2011-06-06 19:25 +0200 http://bitbucket.org/pypy/pypy/changeset/5904225493ed/
Log: merge heads 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 */ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit