From jkrell at elego.de Mon Jan 3 14:14:25 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:14:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103131425.63E4A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:14:25 Removed files: cm3/m3-libs/m3core/src/runtime/SPARC64_SOLARIS/: RTMachine.i3 m3makefile Log message: remove unused files From jkrell at elego.de Mon Jan 3 14:26:53 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:26:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103132656.309102474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:26:53 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapStats.i3 Log message: one newline at end of file suffices From jkrell at elego.de Mon Jan 3 14:57:45 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:57:45 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103135745.B1B6A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:57:45 Modified files: cm3/m3-libs/m3core/src/runtime/ALPHA_OSF/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/SOLsun/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 RTMachine.i3 Log message: Use 64K pages everywhere -- less target dependent code, basically. The page size used to be target dependent when the garbage collector interacted with virtual memory. Now it is basically not machine dependent, except that on Windows we use VirtualAlloc, which always allocates on 64K boundaries, even if you ask for less than 64K, so allocation less than 64K ends up completely wasting memory. This could be viewed negatively as giving the Windows-dependent value to all targets. But I think it is ok. From jkrell at elego.de Mon Jan 3 15:05:36 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:05:36 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103140536.2BCBD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:05:36 Removed files: cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 RTStackASM.s RTStackC.c m3makefile Log message: This code has a high ratio of bug workarounds and reverse engineering. And it is long dead -- I believe it is for Ultrix on MIPS. Delete it. If someone brings back Ultrix (in an emulator?)... From jkrell at elego.de Mon Jan 3 15:13:04 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:13:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103141304.4E7262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:13:04 Modified files: cm3/m3-libs/m3core/src/runtime/NT386/: m3makefile cm3/m3-libs/m3core/src/runtime/common/: m3makefile Removed files: cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 Log message: use common RTMachine.i3 From jkrell at elego.de Tue Jan 4 12:21:56 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 12:21:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104112156.2F9952474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 12:21:56 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 Log message: fix warning: remove unused import RTMachine From jkrell at elego.de Tue Jan 4 13:48:34 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 13:48:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104124834.AF0222474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 13:48:34 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 cm3/m3-libs/m3core/src/C/: m3makefile cm3/m3-libs/m3core/src/C/Common/: m3makefile cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 Added files: cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 Removed files: cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile Log message: Set jumpbuf_align to 64 for all targets. We'd really like to use 2 * BYTESIZE(INTEGER) for all targets except PPC_LINUX, but that isn't expressible. This is therefore as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, and non-ideal for PPC_LINUX, roughly the same as it ever was (well, the middle end got it right, but the runtime didn't, and they do need to match; so it was seemingly wrong, but somehow worked on PPC_LINUX) In future, hopefully, compiler will inject the type instead of depending on it being declared elsewhere in Modula-3. In future, hopefully, this code will fall away on the majority of platforms/users -- i.e. if we use the gcc stack walker. But it will still stay around in some form for portability to non-gcc platforms. So injecting the type is still desirable. This removes lots of target-dependence. This has the downside of introducing an extra 4 bytes of unnecessary frame size on platforms where 4 byte alignment of jmpbuf is sufficient. (Note that we have and continue to bloat the jmpbuf for other reasons. - sometimes it was sigjmpbuf, no longe - sometimes it is plain wrong, e.g. LINUXLIBC6, still - sometimes for hypothetical interop e.g. NT <=> Interix) If RaiseActivation were one more or one less word, or if the frame has an otherwise odd number of words, the wastage should be removable by offseting the location of RaiseActivation. That is, alignment should be achievable by via hole, but via offseting the enclosing base and possibly using the hole that that creates. In either case, I'm inclined to go one step further and pass an extern const to alloca and only put a pointer to the jmpbuf in the "EF1", dramatically further eliminating target-dependence. We are already calling pthread_getspecific and setjmp, so alloca seems maybe a further reasonable deoptimization in an already slow path. Perhaps we could somehow combine the calls (not easy, given how setjmp and alloca are so special). This would presumably also address the alignment problem -- assuming alloca knows to return a pointer aligned enough for "anything", i.e. including a jmpbuf. There are still some platform-dependent Csetjmp.i3 files (NT) in order to call longjmp instead of the more common _longjmp. Testing, reading headers, and/or disasm will hopefully show that such platforms have _longjmp and it is equivalent. Soon. From jkrell at elego.de Tue Jan 4 14:04:53 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:04:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104130453.9D7152474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:04:53 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 Log message: fix comment: "efficient" => "inefficient" From jay.krell at cornell.edu Tue Jan 4 14:03:17 2011 From: jay.krell at cornell.edu (Jay K) Date: Tue, 4 Jan 2011 13:03:17 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110104124834.AF0222474003@birch.elegosoft.com> References: <20110104124834.AF0222474003@birch.elegosoft.com> Message-ID: straightforward diff attached > Date: Tue, 4 Jan 2011 13:48:34 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/04 13:48:34 > > Modified files: > cm3/m3-sys/m3middle/src/: Target.m3 > cm3/m3-libs/m3core/src/C/: m3makefile > cm3/m3-libs/m3core/src/C/Common/: m3makefile > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > Added files: > cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 > Removed files: > cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile > > Log message: > Set jumpbuf_align to 64 for all targets. > > We'd really like to use 2 * BYTESIZE(INTEGER) for all targets > except PPC_LINUX, but that isn't expressible. This is therefore > as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, > and non-ideal for PPC_LINUX, roughly the same as it ever was > (well, the middle end got it right, but the runtime didn't, > and they do need to match; so it was seemingly wrong, but > somehow worked on PPC_LINUX) > > In future, hopefully, compiler will inject the type instead > of depending on it being declared elsewhere in Modula-3. > > In future, hopefully, this code will fall away on the majority > of platforms/users -- i.e. if we use the gcc stack walker. > But it will still stay around in some form for portability > to non-gcc platforms. So injecting the type is still desirable. > > This removes lots of target-dependence. > This has the downside of introducing an extra 4 bytes of unnecessary > frame size on platforms where 4 byte alignment of jmpbuf is sufficient. > (Note that we have and continue to bloat the jmpbuf for other reasons. > - sometimes it was sigjmpbuf, no longe > - sometimes it is plain wrong, e.g. LINUXLIBC6, still > - sometimes for hypothetical interop e.g. NT <=> Interix) > > If RaiseActivation were one more or one less word, > or if the frame has an otherwise odd number of words, > the wastage should be removable by offseting the location > of RaiseActivation. That is, alignment should be achievable > by via hole, but via offseting the enclosing base and > possibly using the hole that that creates. > > In either case, I'm inclined to go one step further and pass > an extern const to alloca and only put a pointer to the jmpbuf > in the "EF1", dramatically further eliminating target-dependence. > We are already calling pthread_getspecific and setjmp, so alloca > seems maybe a further reasonable deoptimization in an already slow path. > Perhaps we could somehow combine the calls (not easy, given > how setjmp and alloca are so special). This would presumably > also address the alignment problem -- assuming alloca knows > to return a pointer aligned enough for "anything", i.e. including > a jmpbuf. > > There are still some platform-dependent Csetjmp.i3 files (NT) > in order to call longjmp instead of the more common _longjmp. > Testing, reading headers, and/or disasm will hopefully show > that such platforms have _longjmp and it is equivalent. Soon. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf64.txt URL: From jkrell at elego.de Tue Jan 4 14:14:52 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:14:52 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131452.1DA622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:14:52 Added files: cm3/scripts/config/: alloca_alignment.c Log message: program to see how aligned alloca() result is From jkrell at elego.de Tue Jan 4 14:15:11 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:15:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131511.F3A3D2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:15:11 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: show more bits From jkrell at elego.de Tue Jan 4 14:23:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:23:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104132325.5B1682474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:23:25 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: alloca.h on some platforms needed, e.g. Solaris From jkrell at elego.de Tue Jan 4 20:27:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 20:27:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104192725.362E32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 20:27:25 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: Makefile.in tree-ssa-loop.c cm3/m3-sys/m3cc/src/: clean_marker.txt Removed files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-loop-linear.c Log message: Remove tree-loop-linear optimization pass, which the gcc developers are considering removing since it is apparently broken. See http://gcc.gnu.org/ml/gcc/2011-01/msg00056.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00133.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00143.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00146.html cleanup a little graphite stuff (graphite/cloog/ppl refers to loop optimizations in gcc that are dependent upon additional libraries being available, similar to the situation with gmp/mpfr/mpc, but that they are optional even in unpatched gcc) From jkrell at elego.de Tue Jan 4 21:43:37 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:43:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204337.97F562474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:43:37 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: ipa-reference.c tree-vect-stmts.c Log message: fix warnings by removing unused function and locals From jkrell at elego.de Tue Jan 4 21:47:27 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:47:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204727.E9BB82474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:47:27 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-ssa-loop-niter.c Log message: fix some warnings, ATTRIBUTE_UNUSED on unused parameters From jkrell at elego.de Wed Jan 5 15:08:19 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:08:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105140819.DE2A1CC110@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:08:19 Modified files: cm3/m3-sys/m3back/src/: M3C.m3 Log message: flush minor change that was sitting around, not yet really in use From jkrell at elego.de Wed Jan 5 15:16:04 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:16:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141604.2D23C2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:16:04 Modified files: cm3/scripts/config/: stack_direction.c Log message: flush minor change: make it look just like m3core From jkrell at elego.de Wed Jan 5 15:17:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:17:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141751.9A9622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:17:51 Modified files: cm3/scripts/config/: stack_direction.c Log message: more like m3core From jkrell at elego.de Wed Jan 5 15:19:28 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:19:28 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141928.30CB32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:19:28 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: comments only From jkrell at elego.de Wed Jan 5 15:20:03 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:20:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142003.5C442CC123@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:20:03 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: another possible inline suppression From jkrell at elego.de Wed Jan 5 15:21:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:21:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142151.23B672474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:21:51 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: const => EXTERN_CONST This makes it mean the same thing in all C and C++ compilers. Just plain "extern const" would do the same, but that gcc warns for this correct unambiguous portable usage.. From jkrell at elego.de Wed Jan 5 15:25:37 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:25:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142537.AB0932474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:25:37 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: whitespace only, so that subsequent change lines up w/o adding the whitespace change From jkrell at elego.de Wed Jan 5 15:34:55 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:34:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105143455.087E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:34:55 Modified files: cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 Log message: use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); alloca(Csetjmp__Jumpbuf_size) to allocate jmp_buf - eliminates a large swath of target-dependent code - allows for covering up the inability to declare types with alignment > 64 bits It is, granted, a little bit slower, in an already prety slow path. Note that alloca isn't actually a function call, at least with gcc backend. From jay.krell at cornell.edu Wed Jan 5 15:37:12 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 14:37:12 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105143455.087E22474003@birch.elegosoft.com> References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf_alloca.txt URL: From jkrell at elego.de Wed Jan 5 18:32:01 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 18:32:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105173201.5A1742474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 18:32:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: Don't use __thread on Solaris. It failed to link. See: http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console From dabenavidesd at yahoo.es Wed Jan 5 19:10:27 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 18:10:27 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105173201.5A1742474003@birch.elegosoft.com> Message-ID: <167906.41482.qm@web29707.mail.ird.yahoo.com> Hi all: Are this failures linked to a trac ticket with an appropriate tag, would be a quality of service improvement to link to it automatically? I think if the failures of compiler, system compiler, compiler back end, linker, system linker or checker and/or theorem prover, we should produce automatically a ticket assigned for the "guilty" or some else if so, so one can be warned more directly and solve it accordingly, what do you think? I assume some simple changes are or can be back up if so there is a clear compile time error cause and solution. But for everything else is good? I mean might be the ideal with wiki service open we can improve documentation and process on it. Thanks in advance --- El mi?, 5/1/11, Jay Krell escribi?: > De: Jay Krell > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: mi?rcoles, 5 de enero, 2011 13:32 > CVSROOT: /usr/cvs > Changes by: > jkrell at birch. 11/01/05 18:32:01 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: > ThreadPThreadC.c > > Log message: > Don't use __thread on Solaris. > It failed to link. > See: > http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console > > From hosking at cs.purdue.edu Wed Jan 5 19:35:59 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 13:35:59 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 21:44:08 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 20:44:08 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 23:40:25 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 22:40:25 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Thu Jan 6 00:31:08 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 23:31:08 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: Message-ID: <381607.89212.qm@web29720.mail.ird.yahoo.com> Hi all: I wonder how we could make the static M3CG stack allocation tracing verified so not overflow can occur and so make a progress with that compiler obligation too. I suppose every thing we can put in the stack instead of the heap is less efficient in compiler and the checker times but in terms of execution less slower than it would without it. I recall just an experiment with the ESC to check DISPOSE statement (side effecting) instruction will not corrupt the heap with the ESC, kind of interesting for the help M3CG to disable compiler inserted useless garbage collector calls and if so usable inside the stack boundaries for checking unused stack allocated callee? for instance inside the bug commented by Mika on see: https://mail.elegosoft.com/pipermail/m3devel/2010-December/008330.html perhaps a mapping of the M3CG typed implementation if we have already a reference to that unreachable code and if so will it be called or not according to the compiler code generator, in such a case there is a on-live dynamic linking it will just like it could prove it or not to not disable those callers, we would need to automatically infer the annotations for the checker to M3CG ?-instructions and feed for the checker and prover that too. This would be useful not just for the compiler, but for the programmer too, don't you think? Also this would be straightforward to demonstrative of a program that is not to overflow or underflow by popping out anyhow, another missing check in current compilers technology as of what I currently know. Besides that one must check the arithmetic overflow, that would need more of the ESC normal technology by now, though we could explicitly check for it in the searched errors too, again typing the M3CG ?-instructions will gave some of the neeeded info I guess and by emulating ALU logic we could also warn proof that anything would happen in some point if contracts are fulfilled. ?? Thanks in advance --- El mi?, 5/1/11, Jay K escribi?: De: Jay K Asunto: Re: [M3commit] CVS Update: cm3 Para: "Tony" CC: m3commit at elegosoft.com Fecha: mi?rcoles, 5 de enero, 2011 17:40 I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. ?- Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 #yiv448101372 .yiv448101372ExternalClass .yiv448101372ecxhmmessage P {padding:0px;} #yiv448101372 .yiv448101372ExternalClass body.yiv448101372ecxhmmessage {font-size:10pt;font-family:Tahoma;} I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? ?I don't know what has been done here without diving into the diff. Antony Hosking?|?Associate Professor?| Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice?+1 765 494 6001 |?Mobile?+1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To:?m3commit at elegosoft.com > From:?jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 >? > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 >? > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3? > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3? > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c? > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c? > cm3/m3-sys/m3front/src/misc/: Marker.m3? > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3? > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3? >? > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) >? > to allocate jmp_buf >? > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits >? > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. >? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 01:17:01 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:17:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106001701.1620F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:17:00 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Main.m3 m3makefile Log message: a test case from Mika currently results in: new source -> compiling Main.m3 "../Main.m3", line 21: warning: potentially unhandled exception: OSError.E "../Main.m3", line 18: warning: potentially unhandled exception: Thread.Alerted "../Main.m3", line 16: warning: not used (DumpOne) "../Main.m3", line 15: warning: not used (DumpMatching) 4 warnings encountered ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [66]) (const_int 0 [0x0])) (set (reg:SI 1 dx [64]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 1 dx [64]))) (set (reg:SI 4 si [65]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 4 si [65]))) (set (mem/s/c:BLK (reg:SI 1 dx [64]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg:SI 4 si [65]) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [66])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [66]) (expr_list:REG_UNUSED (reg:SI 4 si [65]) (expr_list:REG_UNUSED (reg:SI 1 dx [64]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. m3_backend => 4 m3cc (aka cm3cg) failed compiling: Main.mc compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:25:08 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:25:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002508.623F92474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:25:08 Added files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 m3makefile Log message: another test case from Mika jbook2:p250 jay$ cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 1: 1 code generation error 1 error encountered compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:26:15 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:26:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002615.77E782474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:26:15 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: slightly simpler, same error From hosking at cs.purdue.edu Thu Jan 6 02:21:11 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:21:11 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: <3AC78E33-81AB-49EF-B566-468EF601BC36@cs.purdue.edu> Do you alloca on every TRY or once in procedures that have a TRY? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 3:44 PM, Jay K wrote: > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 02:23:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:23:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote: > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:25:03 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:25:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106012503.90C392474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:25:03 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: much simpler, same error From jay.krell at cornell.edu Thu Jan 6 02:33:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 01:33:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:33:51 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:33:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013351.4AB262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:33:51 Modified files: cm3/m3-sys/m3tests/src/: Test.i3 TestC.c Log message: fix now that Csetjmp is unsafe, and that we don't need to check the size of jmpbuf From jkrell at elego.de Thu Jan 6 02:38:38 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:38:38 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013838.D102B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:38:38 Added files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 m3makefile Log message: starting some new test code to nail down try/finally/except/lock stuff not yet done, taking short break From hosking at cs.purdue.edu Thu Jan 6 02:49:24 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:49:24 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote: > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 03:08:47 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 02:08:47 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 03:14:17 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 21:14:17 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 03:32:11 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 3:32:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106023211.9CC57CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 03:32:11 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: work in progress From jkrell at elego.de Thu Jan 6 04:42:30 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 4:42:30 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106034231.3E0E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 04:42:30 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p250/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p251/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 Log message: perhaps slightly controversial: add new tests in old branch This is a little easier to test/compare and the downside should be negligible -- downside of polluting history. From jay.krell at cornell.edu Thu Jan 6 05:52:33 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 04:52:33 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 07:02:26 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 06:02:26 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 08:18:41 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 8:18:41 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106071841.7E2072474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 08:18:41 Modified files: cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/runtime/ex_stack/: RTExStack.m3 Log message: comments only; in particular put in "see also" indicating these files describe each other From hosking at cs.purdue.edu Thu Jan 6 15:19:36 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:19:36 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: <6DAAF11E-4EA3-4D9E-BFBE-4B15D2B873F5@cs.purdue.edu> No, if there are n static TRY block sites, then up to n calls to alloca is OK. I am assuming you test for NIL at each site and alloca only if NIL. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 11:52 PM, Jay K wrote: > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 15:22:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:22:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. 2. If not, then alloca and save its pointer in the local variable 3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 17:29:44 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 17:29:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106162944.39C442474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 17:29:44 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: more tests From jay.krell at cornell.edu Thu Jan 6 17:35:43 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 16:35:43 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. I guess, really, it is EF1, EF2, etc. So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. something like: PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; => void F1() { jmp_buf* jb = 0; EF1 a,b,c; setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 do stuff 1... setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 do stuff 2... setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 do stuff 3... } (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) Still, something I can't pin down strikes me as too simple here. If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. That doesn't seem adequate. What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? It won't know where to resume, right? It's just keep longjmping to the same place. In the Visual C++ runtime, there is "local unwind" and "global unwind". "local unwind" is like, "within the same functin", "global unwind" is across functions. I think somehow that is related here. e.g. how would you ensure forward progress in this: EXCEPTION E1; EXCEPTION E2; EXCEPTION E3; PROCEDURE F4() RAISES ANY = CONST Function = "F4 "; BEGIN Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); RAISE E1; EXCEPT ELSE RAISE E2; END; EXCEPT ELSE RAISE E3; END; EXCEPT ELSE END; END F4; Oddly in my test p251, the stack depth is not increased by TRY. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Thu, 6 Jan 2011 09:22:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL.2. If not, then alloca and save its pointer in the local variable3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 18:08:47 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 18:08:47 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106170847.442592474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 18:08:47 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: aha! loop with try, not good From hosking at cs.purdue.edu Thu Jan 6 19:52:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 13:52:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> You can't have one jmpbuf per procedure. You need one per TRY scope, since they can be nested. On Jan 6, 2011, at 11:35 AM, Jay K wrote: > Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 20:00:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 19:00:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: I believe you can, but it'd take significant work in the frontend. The jmpbuf should identify merely which procedure/frame to return to. There would also be a volatile local integer, that gets altered at certain points through the function. When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. Instead of setjmp, the compiler pessimizes appropriately. So the result is that a function with one or more tries, or one or more locals with destructors, puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate where in the function it is. If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. It is more work through, granted, I can understand that. And given that we have a much better option for many platforms, the payoff would be reduced. Anyway, I'm trying what you say, like for TRY within a loop. I should point out that alloca has an extra inefficiency vs. the previous approach. It aligns more. So it is using more stack than the other way. And it might pessimize codegen in other ways. The gcc code appears somewhat similar..I think the tables merely describe, again, which function/frame to return to, and that within the frame there is a local integer to determine more precisely what to do. I'm not sure. I saw mention of a switch. ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 13:52:42 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You can't have one jmpbuf per procedure. You need one per TRY scope, > since they can be nested. > > > > On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > Hm. How do I single instance the "EF1"? The current code allocates a > local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store > it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how > to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the > existance of the ternary operator, and that it only evaluates one side > or the other, and that assignment is expression..I quite like those > features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of > additional progress, you only ever know the last place you were in a > function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and > then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the > same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is > across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking > if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the > compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation > is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one > setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then > live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly > possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your > point is, you'd rather have n locals, which the backend automatically > merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to > setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if > setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific > per function > - The calls to alloca could be merged. The frontend could keep track > of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? > Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY > block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of > the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, > it calls setjmp once. > And then, it should have one volatile integer, that in a sense > represents the line number. > But not really. It's like, every time you cross a TRY, the integer is > incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the > value can be stored. > And then there is a maximum of one one handler per function, it > switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix > it -- check for NIL. > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > are allocating on every TRY where previously the storage was statically > allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is > actually fairly small to read. > I understand it is definitely less efficient, a few more instructions > for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change > is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there > probably is a function call there. > > - Jay > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in > EF1 is now allocated with alloca, and a pointer stored. It is > definitely a bit less efficient, but the significant advantage is > frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to > more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > to align to 16 bytes. I don't have an HPUX machine currently to see if > the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack > walker. I wanted to do this first though, while more targets using > setjmp. > > - Jay/phone > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what > has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > > From hosking at cs.purdue.edu Thu Jan 6 20:11:04 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 14:11:04 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > I believe you can, but it'd take significant work in the frontend. > The jmpbuf should identify merely which procedure/frame to return to. > There would also be a volatile local integer, that gets altered at certain points through the function. > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > Instead of setjmp, the compiler pessimizes appropriately. > > > So the result is that a function with one or more tries, or one or more locals with destructors, > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > where in the function it is. > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > It is more work through, granted, I can understand that. > And given that we have a much better option for many platforms, the payoff would be reduced. > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > It aligns more. So it is using more stack than the other way. > And it might pessimize codegen in other ways. > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > function/frame to return to, and that within the frame there is a local integer to determine > more precisely what to do. I'm not sure. I saw mention of a switch. > > > - Jay > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 13:52:42 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> You can't have one jmpbuf per procedure. You need one per TRY scope, >> since they can be nested. >> >> >> >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >> >> Hm. How do I single instance the "EF1"? The current code allocates a >> local "EF1" for each try. >> I guess, really, it is EF1, EF2, etc. >> So there should be a separate local for the jmpbuf pointer, and store >> it in each EF* block? >> How do I make just one jmpbuf pointer? I couldn't easily figure out how >> to in the front end, I need to read it more. >> >> something like: >> >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >> END END END END F1; >> => >> >> void F1() >> { >> jmp_buf* jb = 0; >> EF1 a,b,c; >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >> do stuff 1... >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >> do stuff 2... >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >> do stuff 3... >> } >> >> (The actual syntactic and semantic correctness of this code -- the >> existance of the ternary operator, and that it only evaluates one side >> or the other, and that assignment is expression..I quite like those >> features....) >> >> >> Still, something I can't pin down strikes me as too simple here. >> >> >> If there is just one setjmp, and no integer(s) to keep track of >> additional progress, you only ever know the last place you were in a >> function. >> That doesn't seem adequate. >> >> >> What if a function raises an exception, catches it within itself, and >> then raises something else, and then wants to catch that? >> It won't know where to resume, right? It's just keep longjmping to the >> same place. >> >> >> In the Visual C++ runtime, there is "local unwind" and "global unwind". >> "local unwind" is like, "within the same functin", "global unwind" is >> across functions. >> I think somehow that is related here. >> >> >> e.g. how would you ensure forward progress in this: >> >> >> EXCEPTION E1; >> EXCEPTION E2; >> EXCEPTION E3; >> >> >> PROCEDURE F4() RAISES ANY = >> CONST Function = "F4 "; >> BEGIN >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> RAISE E1; >> EXCEPT ELSE >> RAISE E2; >> END; >> EXCEPT ELSE >> RAISE E3; >> END; >> EXCEPT ELSE >> END; >> END F4; >> >> >> Oddly in my test p251, the stack depth is not increased by TRY. >> >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 09:22:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I am OK with what you have currently: >> >> At each TRY: >> >> 1. Check if a corresponding alloca block has been allocated by checking >> if the corresponding local variable is NIL. >> 2. If not, then alloca and save its pointer in the local variable >> 3. Execute the try block. >> >> As you say, alloca should turn into an inline operation using the >> compiler's builtin implementation of alloca. >> >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >> >>> Code size will suffer. >> >> >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >> I thought it'd only be one call. I didn't realize our implementation >> is as poor as it is, since a better but still >> portable implementation doesn't seem too too difficult. >> >> >> Can we maybe do the optimizations I indicate -- no more than one >> setjmp/alloca/pushframe per function? >> Using a local integer to record the position within the function? >> >> >> Or just give me a week or few to get stack walking working and then >> live the regression on other targets? >> (NT386 isn't likely to get stack walking, though it *is* certainly >> possible; NT does have a decent runtime here..) >> >> >> It *is* nice to not have have the frontend know about jmpbuf size. >> >> >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >> It doesn't work for intra-function jumps, only inter-function. >> >> >> - Jay >> >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 04:52:33 +0000 >> >> Ah..I'm doing more comparisons of release vs. head...but..I guess your >> point is, you'd rather have n locals, which the backend automatically >> merges, than n calls to alloca? >> It's not a huge difference -- there are still going to be n calls to >> setjmp and n calls to pthread_getspecific. >> The alloca calls will be dwarfed. >> Code size will suffer. >> >> >> And, even so, there are plenty of optimizations to be had, even if >> setjmp/pthread_getspecific is used. >> >> >> - It could make a maximum of one call to setjmp/pthread_getspecific >> per function >> - The calls to alloca could be merged. The frontend could keep track >> of how many calls it makes per function, >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >> >> >> So, yes, given my current understanding, it is progress. >> The target-dependence is not worth it, imho. >> I'll still do some comparisons to release. >> >> >> I'll still be looking into using the gcc unwinder relatively soon. >> >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 21:14:17 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >> >> Tony, um..well, um.. first, isn't that how it already worked maybe? >> Declaring a new local EF1 for each TRY? It looks like it. >> I'll do more testing. >> >> Yes, it did. I assume you simply have a local variable for each TRY >> block that is a pointer now instead of a jmp_buf. Should be OK. >> >> >> So the additional inefficiency is multiplied the same as the rest of >> the preexisting inefficiency. >> And the preexisting inefficiency is way more than the increase. >> >> And second, either way, it could be better. >> >> Basically, the model should be, that if a function has any try or lock, >> it calls setjmp once. >> And then, it should have one volatile integer, that in a sense >> represents the line number. >> But not really. It's like, every time you cross a TRY, the integer is >> incremented, every time you >> cross a finally or unlock, the integer is decremented. Or rather, the >> value can be stored. >> And then there is a maximum of one one handler per function, it >> switches on the integer >> to decide where it got into the function and what it should do. >> >> This is how other compilers work and it is a fairly simple sensible approach. >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:49:24 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Note that you need a different jmpbuf for each nested TRY! >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >> >> oops, that's not how I thought it worked. I'll do more testing and fix >> it -- check for NIL. >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:23:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >> are allocating on every TRY where previously the storage was statically >> allocated. Do you really think this is progress? >> >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >> >> I've back with full keyboard if more explanation needed. The diff is >> actually fairly small to read. >> I understand it is definitely less efficient, a few more instructions >> for every try/lock. >> No extra function call, at least with gcc backend. >> I haven't tested NT386 yet. Odds are so/so that it works -- the change >> is written so that it should work >> but I have to test it to be sure, will to roughly tonight. And there >> probably is a function call there. >> >> - Jay >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:44:08 +0000 >> CC: m3commit at elegosoft.com >> Subject: Re: [M3commit] CVS Update: cm3 >> >> I only have phone right now. I think it is fairly clear: the jumpbuf in >> EF1 is now allocated with alloca, and a pointer stored. It is >> definitely a bit less efficient, but the significant advantage is >> frontend no longer needs to know the size or alignment of a jumpbuf. >> >> >> As well, there is no longer the problem regarding jumpbuf aligned to >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >> to align to 16 bytes. I don't have an HPUX machine currently to see if >> the problem is addressed there. >> >> >> The inefficiency of course can be dramatically mitigated via a stack >> walker. I wanted to do this first though, while more targets using >> setjmp. >> >> - Jay/phone >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 13:35:59 -0500 >> CC: jkrell at elego.de; m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Can you provide a more descriptive checkin comment? I don't know what >> has been done here without diving into the diff. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >> >> diff attached >> >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>> To: m3commit at elegosoft.com >>> From: jkrell at elego.de >>> Subject: [M3commit] CVS Update: cm3 >>> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>> >>> Log message: >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>> alloca(Csetjmp__Jumpbuf_size) >>> >>> to allocate jmp_buf >>> >>> - eliminates a large swath of target-dependent code >>> - allows for covering up the inability to declare >>> types with alignment > 64 bits >>> >>> It is, granted, a little bit slower, in an already prety slow path. >>> Note that alloca isn't actually a function call, at least with gcc backend. >>> >> >> >> >> >> >> >> >> >> >> >> >> > From jay.krell at cornell.edu Thu Jan 6 21:33:21 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:33:21 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: Ok. Do you know where to initialize the jmpbuf to NIL? I have a diff that "works" (ie: doesn't crash) and is *close* to correct, it checks for NIL and branches around the alloca for non-NIL, but it also initializes to NIL repeatedly, so no change effectively. ? Index: misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.7 diff -u -w -r1.7 Marker.m3 --- misc/Marker.m3??? 5 Jan 2011 14:34:54 -0000??? 1.7 +++ misc/Marker.m3??? 6 Jan 2011 20:32:00 -0000 @@ -233,6 +233,7 @@ ? ?PROCEDURE CaptureState (frame: CG.Var;? handler: CG.Label) = ?? VAR new: BOOLEAN; +????? label := CG.Next_label (); ?? BEGIN ???? (* int setjmp(void* ); *) ???? IF (setjmp = NIL) THEN @@ -263,18 +264,25 @@ ???????????????????????????????????????? Target.Word.cg_type, 0); ???? END; ???? +??? (* IF frame.jmpbuf = NIL THEN *) + +????? CG.Load_nil (); +????? CG.Load_addr (frame, M3RT.EF1_jmpbuf); +????? CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); + ???? (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) ???? CG.Start_call_direct (alloca, 0, Target.Address.cg_type); ???? CG.Load_int (Target.Word.cg_type, Jumpbuf_size); ???? CG.Pop_param (Target.Word.cg_type); ???? CG.Call_direct (alloca, Target.Address.cg_type); -??? CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -????????????? Target.Address.cg_type); +????? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + +??? (* END *) +??? CG.Set_label (label); ? ???? (* setmp(frame.jmpbuf) *) ???? CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); -??? CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -???????????? Target.Address.cg_type); +??? CG.Load_addr (frame, M3RT.EF1_jmpbuf); ???? CG.Pop_param (CG.Type.Addr); ???? CG.Call_direct (setjmp, Target.Integer.cg_type); ???? CG.If_true (handler, CG.Never); cvs diff: Diffing stmts Index: stmts/TryFinStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v retrieving revision 1.6 diff -u -w -r1.6 TryFinStmt.m3 --- stmts/TryFinStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.6 +++ stmts/TryFinStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -299,6 +299,10 @@ ???? CG.Load_nil (); ???? CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? l := CG.Next_label (3); ???? CG.Set_label (l, barrier := TRUE); ???? Marker.PushFrame (frame, M3RT.HandlerClass.Finally); Index: stmts/TryStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v retrieving revision 1.3 diff -u -w -r1.3 TryStmt.m3 --- stmts/TryStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.3 +++ stmts/TryStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -10,7 +10,7 @@ ? ?IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; ?IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; -IMPORT Scanner, ESet, Target, M3RT, Tracer; +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; ?FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; ? ?TYPE @@ -411,6 +411,10 @@ ???? CG.Store_addr (frame, M3RT.EF1_exception); ???? ***********************************************) ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? IF (p.hasElse) THEN ?????? Marker.PushTryElse (l, l+1, frame); ?????? Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); The set_label before one of the PushEFrames could be moved down a bit, to after the NIL initialization, and that'd fix some cases, but I think not all. Thanks, - Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 14:11:04 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > > > > I believe you can, but it'd take significant work in the frontend. > > The jmpbuf should identify merely which procedure/frame to return to. > > There would also be a volatile local integer, that gets altered at certain points through the function. > > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > Instead of setjmp, the compiler pessimizes appropriately. > > > > > > So the result is that a function with one or more tries, or one or more locals with destructors, > > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > where in the function it is. > > > > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > > > > It is more work through, granted, I can understand that. > > And given that we have a much better option for many platforms, the payoff would be reduced. > > > > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > > It aligns more. So it is using more stack than the other way. > > And it might pessimize codegen in other ways. > > > > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > > function/frame to return to, and that within the frame there is a local integer to determine > > more precisely what to do. I'm not sure. I saw mention of a switch. > > > > > > - Jay > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> You can't have one jmpbuf per procedure. You need one per TRY scope, > >> since they can be nested. > >> > >> > >> > >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >> > >> Hm. How do I single instance the "EF1"? The current code allocates a > >> local "EF1" for each try. > >> I guess, really, it is EF1, EF2, etc. > >> So there should be a separate local for the jmpbuf pointer, and store > >> it in each EF* block? > >> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >> to in the front end, I need to read it more. > >> > >> something like: > >> > >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >> END END END END F1; > >> => > >> > >> void F1() > >> { > >> jmp_buf* jb = 0; > >> EF1 a,b,c; > >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >> do stuff 1... > >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >> do stuff 2... > >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >> do stuff 3... > >> } > >> > >> (The actual syntactic and semantic correctness of this code -- the > >> existance of the ternary operator, and that it only evaluates one side > >> or the other, and that assignment is expression..I quite like those > >> features....) > >> > >> > >> Still, something I can't pin down strikes me as too simple here. > >> > >> > >> If there is just one setjmp, and no integer(s) to keep track of > >> additional progress, you only ever know the last place you were in a > >> function. > >> That doesn't seem adequate. > >> > >> > >> What if a function raises an exception, catches it within itself, and > >> then raises something else, and then wants to catch that? > >> It won't know where to resume, right? It's just keep longjmping to the > >> same place. > >> > >> > >> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >> "local unwind" is like, "within the same functin", "global unwind" is > >> across functions. > >> I think somehow that is related here. > >> > >> > >> e.g. how would you ensure forward progress in this: > >> > >> > >> EXCEPTION E1; > >> EXCEPTION E2; > >> EXCEPTION E3; > >> > >> > >> PROCEDURE F4() RAISES ANY = > >> CONST Function = "F4 "; > >> BEGIN > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> RAISE E1; > >> EXCEPT ELSE > >> RAISE E2; > >> END; > >> EXCEPT ELSE > >> RAISE E3; > >> END; > >> EXCEPT ELSE > >> END; > >> END F4; > >> > >> > >> Oddly in my test p251, the stack depth is not increased by TRY. > >> > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> I am OK with what you have currently: > >> > >> At each TRY: > >> > >> 1. Check if a corresponding alloca block has been allocated by checking > >> if the corresponding local variable is NIL. > >> 2. If not, then alloca and save its pointer in the local variable > >> 3. Execute the try block. > >> > >> As you say, alloca should turn into an inline operation using the > >> compiler's builtin implementation of alloca. > >> > >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >> > >>> Code size will suffer. > >> > >> > >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >> I thought it'd only be one call. I didn't realize our implementation > >> is as poor as it is, since a better but still > >> portable implementation doesn't seem too too difficult. > >> > >> > >> Can we maybe do the optimizations I indicate -- no more than one > >> setjmp/alloca/pushframe per function? > >> Using a local integer to record the position within the function? > >> > >> > >> Or just give me a week or few to get stack walking working and then > >> live the regression on other targets? > >> (NT386 isn't likely to get stack walking, though it *is* certainly > >> possible; NT does have a decent runtime here..) > >> > >> > >> It *is* nice to not have have the frontend know about jmpbuf size. > >> > >> > >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >> It doesn't work for intra-function jumps, only inter-function. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >> > >> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >> point is, you'd rather have n locals, which the backend automatically > >> merges, than n calls to alloca? > >> It's not a huge difference -- there are still going to be n calls to > >> setjmp and n calls to pthread_getspecific. > >> The alloca calls will be dwarfed. > >> Code size will suffer. > >> > >> > >> And, even so, there are plenty of optimizations to be had, even if > >> setjmp/pthread_getspecific is used. > >> > >> > >> - It could make a maximum of one call to setjmp/pthread_getspecific > >> per function > >> - The calls to alloca could be merged. The frontend could keep track > >> of how many calls it makes per function, > >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >> > >> > >> So, yes, given my current understanding, it is progress. > >> The target-dependence is not worth it, imho. > >> I'll still do some comparisons to release. > >> > >> > >> I'll still be looking into using the gcc unwinder relatively soon. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >> > >> Tony, um..well, um.. first, isn't that how it already worked maybe? > >> Declaring a new local EF1 for each TRY? It looks like it. > >> I'll do more testing. > >> > >> Yes, it did. I assume you simply have a local variable for each TRY > >> block that is a pointer now instead of a jmp_buf. Should be OK. > >> > >> > >> So the additional inefficiency is multiplied the same as the rest of > >> the preexisting inefficiency. > >> And the preexisting inefficiency is way more than the increase. > >> > >> And second, either way, it could be better. > >> > >> Basically, the model should be, that if a function has any try or lock, > >> it calls setjmp once. > >> And then, it should have one volatile integer, that in a sense > >> represents the line number. > >> But not really. It's like, every time you cross a TRY, the integer is > >> incremented, every time you > >> cross a finally or unlock, the integer is decremented. Or rather, the > >> value can be stored. > >> And then there is a maximum of one one handler per function, it > >> switches on the integer > >> to decide where it got into the function and what it should do. > >> > >> This is how other compilers work and it is a fairly simple sensible approach. > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Note that you need a different jmpbuf for each nested TRY! > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >> > >> oops, that's not how I thought it worked. I'll do more testing and fix > >> it -- check for NIL. > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >> are allocating on every TRY where previously the storage was statically > >> allocated. Do you really think this is progress? > >> > >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >> > >> I've back with full keyboard if more explanation needed. The diff is > >> actually fairly small to read. > >> I understand it is definitely less efficient, a few more instructions > >> for every try/lock. > >> No extra function call, at least with gcc backend. > >> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >> is written so that it should work > >> but I have to test it to be sure, will to roughly tonight. And there > >> probably is a function call there. > >> > >> - Jay > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >> CC: m3commit at elegosoft.com > >> Subject: Re: [M3commit] CVS Update: cm3 > >> > >> I only have phone right now. I think it is fairly clear: the jumpbuf in > >> EF1 is now allocated with alloca, and a pointer stored. It is > >> definitely a bit less efficient, but the significant advantage is > >> frontend no longer needs to know the size or alignment of a jumpbuf. > >> > >> > >> As well, there is no longer the problem regarding jumpbuf aligned to > >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >> to align to 16 bytes. I don't have an HPUX machine currently to see if > >> the problem is addressed there. > >> > >> > >> The inefficiency of course can be dramatically mitigated via a stack > >> walker. I wanted to do this first though, while more targets using > >> setjmp. > >> > >> - Jay/phone > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Can you provide a more descriptive checkin comment? I don't know what > >> has been done here without diving into the diff. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >> > >> diff attached > >> > >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>> To: m3commit at elegosoft.com > >>> From: jkrell at elego.de > >>> Subject: [M3commit] CVS Update: cm3 > >>> > >>> CVSROOT: /usr/cvs > >>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>> > >>> Modified files: > >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>> > >>> Log message: > >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>> alloca(Csetjmp__Jumpbuf_size) > >>> > >>> to allocate jmp_buf > >>> > >>> - eliminates a large swath of target-dependent code > >>> - allows for covering up the inability to declare > >>> types with alignment > 64 bits > >>> > >>> It is, granted, a little bit slower, in an already prety slow path. > >>> Note that alloca isn't actually a function call, at least with gcc backend. > >>> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > > > From jkrell at elego.de Thu Jan 6 21:40:16 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 21:40:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106204016.8C4BF2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 21:40:16 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: use convenience Load/Store_addr instead of Load/Store From hosking at cs.purdue.edu Thu Jan 6 21:42:33 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:42:33 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> I don't understand what you mean by "initializes to NIL". How are you creating the frame variable? If you do it properly the language semantics will cause it be initialized to NIL automatically. On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > Ok. > Do you know where to initialize the jmpbuf to NIL? > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > it checks for NIL and branches around the alloca for non-NIL, but it > also initializes to NIL repeatedly, so no change effectively. > > > Index: misc/Marker.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > retrieving revision 1.7 > diff -u -w -r1.7 Marker.m3 > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > @@ -233,6 +233,7 @@ > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > VAR new: BOOLEAN; > + label := CG.Next_label (); > BEGIN > (* int setjmp(void* ); *) > IF (setjmp = NIL) THEN > @@ -263,18 +264,25 @@ > Target.Word.cg_type, 0); > END; > > + (* IF frame.jmpbuf = NIL THEN *) > + > + CG.Load_nil (); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > + > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > CG.Pop_param (Target.Word.cg_type); > CG.Call_direct (alloca, Target.Address.cg_type); > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > + (* END *) > + CG.Set_label (label); > > (* setmp(frame.jmpbuf) *) > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > CG.Pop_param (CG.Type.Addr); > CG.Call_direct (setjmp, Target.Integer.cg_type); > CG.If_true (handler, CG.Never); > cvs diff: Diffing stmts > Index: stmts/TryFinStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > retrieving revision 1.6 > diff -u -w -r1.6 TryFinStmt.m3 > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -299,6 +299,10 @@ > CG.Load_nil (); > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > l := CG.Next_label (3); > CG.Set_label (l, barrier := TRUE); > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > Index: stmts/TryStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > retrieving revision 1.3 > diff -u -w -r1.3 TryStmt.m3 > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -10,7 +10,7 @@ > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > TYPE > @@ -411,6 +411,10 @@ > CG.Store_addr (frame, M3RT.EF1_exception); > ***********************************************) > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > IF (p.hasElse) THEN > Marker.PushTryElse (l, l+1, frame); > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > The set_label before one of the PushEFrames could be moved down a bit, > to after the NIL initialization, and that'd fix some cases, but I think not all. > > Thanks, > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 14:11:04 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >> >>> >>> I believe you can, but it'd take significant work in the frontend. >>> The jmpbuf should identify merely which procedure/frame to return to. >>> There would also be a volatile local integer, that gets altered at certain points through the function. >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>> Instead of setjmp, the compiler pessimizes appropriately. >>> >>> >>> So the result is that a function with one or more tries, or one or more locals with destructors, >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>> where in the function it is. >>> >>> >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>> >>> >>> It is more work through, granted, I can understand that. >>> And given that we have a much better option for many platforms, the payoff would be reduced. >>> >>> >>> Anyway, I'm trying what you say, like for TRY within a loop. >>> >>> >>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>> It aligns more. So it is using more stack than the other way. >>> And it might pessimize codegen in other ways. >>> >>> >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>> function/frame to return to, and that within the frame there is a local integer to determine >>> more precisely what to do. I'm not sure. I saw mention of a switch. >>> >>> >>> - Jay >>> >>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>> since they can be nested. >>>> >>>> >>>> >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>> >>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>> local "EF1" for each try. >>>> I guess, really, it is EF1, EF2, etc. >>>> So there should be a separate local for the jmpbuf pointer, and store >>>> it in each EF* block? >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>> to in the front end, I need to read it more. >>>> >>>> something like: >>>> >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>> END END END END F1; >>>> => >>>> >>>> void F1() >>>> { >>>> jmp_buf* jb = 0; >>>> EF1 a,b,c; >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>> do stuff 1... >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>> do stuff 2... >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>> do stuff 3... >>>> } >>>> >>>> (The actual syntactic and semantic correctness of this code -- the >>>> existance of the ternary operator, and that it only evaluates one side >>>> or the other, and that assignment is expression..I quite like those >>>> features....) >>>> >>>> >>>> Still, something I can't pin down strikes me as too simple here. >>>> >>>> >>>> If there is just one setjmp, and no integer(s) to keep track of >>>> additional progress, you only ever know the last place you were in a >>>> function. >>>> That doesn't seem adequate. >>>> >>>> >>>> What if a function raises an exception, catches it within itself, and >>>> then raises something else, and then wants to catch that? >>>> It won't know where to resume, right? It's just keep longjmping to the >>>> same place. >>>> >>>> >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>> "local unwind" is like, "within the same functin", "global unwind" is >>>> across functions. >>>> I think somehow that is related here. >>>> >>>> >>>> e.g. how would you ensure forward progress in this: >>>> >>>> >>>> EXCEPTION E1; >>>> EXCEPTION E2; >>>> EXCEPTION E3; >>>> >>>> >>>> PROCEDURE F4() RAISES ANY = >>>> CONST Function = "F4 "; >>>> BEGIN >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> RAISE E1; >>>> EXCEPT ELSE >>>> RAISE E2; >>>> END; >>>> EXCEPT ELSE >>>> RAISE E3; >>>> END; >>>> EXCEPT ELSE >>>> END; >>>> END F4; >>>> >>>> >>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>> >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> I am OK with what you have currently: >>>> >>>> At each TRY: >>>> >>>> 1. Check if a corresponding alloca block has been allocated by checking >>>> if the corresponding local variable is NIL. >>>> 2. If not, then alloca and save its pointer in the local variable >>>> 3. Execute the try block. >>>> >>>> As you say, alloca should turn into an inline operation using the >>>> compiler's builtin implementation of alloca. >>>> >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>> >>>>> Code size will suffer. >>>> >>>> >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>> I thought it'd only be one call. I didn't realize our implementation >>>> is as poor as it is, since a better but still >>>> portable implementation doesn't seem too too difficult. >>>> >>>> >>>> Can we maybe do the optimizations I indicate -- no more than one >>>> setjmp/alloca/pushframe per function? >>>> Using a local integer to record the position within the function? >>>> >>>> >>>> Or just give me a week or few to get stack walking working and then >>>> live the regression on other targets? >>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>> possible; NT does have a decent runtime here..) >>>> >>>> >>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>> >>>> >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>> It doesn't work for intra-function jumps, only inter-function. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>> >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>> point is, you'd rather have n locals, which the backend automatically >>>> merges, than n calls to alloca? >>>> It's not a huge difference -- there are still going to be n calls to >>>> setjmp and n calls to pthread_getspecific. >>>> The alloca calls will be dwarfed. >>>> Code size will suffer. >>>> >>>> >>>> And, even so, there are plenty of optimizations to be had, even if >>>> setjmp/pthread_getspecific is used. >>>> >>>> >>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>> per function >>>> - The calls to alloca could be merged. The frontend could keep track >>>> of how many calls it makes per function, >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>> >>>> >>>> So, yes, given my current understanding, it is progress. >>>> The target-dependence is not worth it, imho. >>>> I'll still do some comparisons to release. >>>> >>>> >>>> I'll still be looking into using the gcc unwinder relatively soon. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>> >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>> Declaring a new local EF1 for each TRY? It looks like it. >>>> I'll do more testing. >>>> >>>> Yes, it did. I assume you simply have a local variable for each TRY >>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>> >>>> >>>> So the additional inefficiency is multiplied the same as the rest of >>>> the preexisting inefficiency. >>>> And the preexisting inefficiency is way more than the increase. >>>> >>>> And second, either way, it could be better. >>>> >>>> Basically, the model should be, that if a function has any try or lock, >>>> it calls setjmp once. >>>> And then, it should have one volatile integer, that in a sense >>>> represents the line number. >>>> But not really. It's like, every time you cross a TRY, the integer is >>>> incremented, every time you >>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>> value can be stored. >>>> And then there is a maximum of one one handler per function, it >>>> switches on the integer >>>> to decide where it got into the function and what it should do. >>>> >>>> This is how other compilers work and it is a fairly simple sensible approach. >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Note that you need a different jmpbuf for each nested TRY! >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>> >>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>> it -- check for NIL. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>> are allocating on every TRY where previously the storage was statically >>>> allocated. Do you really think this is progress? >>>> >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>> >>>> I've back with full keyboard if more explanation needed. The diff is >>>> actually fairly small to read. >>>> I understand it is definitely less efficient, a few more instructions >>>> for every try/lock. >>>> No extra function call, at least with gcc backend. >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>> is written so that it should work >>>> but I have to test it to be sure, will to roughly tonight. And there >>>> probably is a function call there. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>> CC: m3commit at elegosoft.com >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>> definitely a bit less efficient, but the significant advantage is >>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>> >>>> >>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>> the problem is addressed there. >>>> >>>> >>>> The inefficiency of course can be dramatically mitigated via a stack >>>> walker. I wanted to do this first though, while more targets using >>>> setjmp. >>>> >>>> - Jay/phone >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Can you provide a more descriptive checkin comment? I don't know what >>>> has been done here without diving into the diff. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>> >>>> diff attached >>>> >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>> To: m3commit at elegosoft.com >>>>> From: jkrell at elego.de >>>>> Subject: [M3commit] CVS Update: cm3 >>>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>> >>>>> Log message: >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>> alloca(Csetjmp__Jumpbuf_size) >>>>> >>>>> to allocate jmp_buf >>>>> >>>>> - eliminates a large swath of target-dependent code >>>>> - allows for covering up the inability to declare >>>>> types with alignment > 64 bits >>>>> >>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 21:48:56 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:48:56 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: The same way as before. I think this operates at too low a level to get any automatic initialization. TryStmt.m3 and TryFinStmt.m3: ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); I agree though, this might not be ideal. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 15:42:33 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I don't understand what you mean by "initializes to NIL". > How are you creating the frame variable? > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > Ok. > > Do you know where to initialize the jmpbuf to NIL? > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > it checks for NIL and branches around the alloca for non-NIL, but it > > also initializes to NIL repeatedly, so no change effectively. > > > > > > Index: misc/Marker.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > retrieving revision 1.7 > > diff -u -w -r1.7 Marker.m3 > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > @@ -233,6 +233,7 @@ > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > VAR new: BOOLEAN; > > + label := CG.Next_label (); > > BEGIN > > (* int setjmp(void* ); *) > > IF (setjmp = NIL) THEN > > @@ -263,18 +264,25 @@ > > Target.Word.cg_type, 0); > > END; > > > > + (* IF frame.jmpbuf = NIL THEN *) > > + > > + CG.Load_nil (); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > + > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > CG.Pop_param (Target.Word.cg_type); > > CG.Call_direct (alloca, Target.Address.cg_type); > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > + (* END *) > > + CG.Set_label (label); > > > > (* setmp(frame.jmpbuf) *) > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > CG.Pop_param (CG.Type.Addr); > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > CG.If_true (handler, CG.Never); > > cvs diff: Diffing stmts > > Index: stmts/TryFinStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > retrieving revision 1.6 > > diff -u -w -r1.6 TryFinStmt.m3 > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -299,6 +299,10 @@ > > CG.Load_nil (); > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > l := CG.Next_label (3); > > CG.Set_label (l, barrier := TRUE); > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > Index: stmts/TryStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > retrieving revision 1.3 > > diff -u -w -r1.3 TryStmt.m3 > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -10,7 +10,7 @@ > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > TYPE > > @@ -411,6 +411,10 @@ > > CG.Store_addr (frame, M3RT.EF1_exception); > > ***********************************************) > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > IF (p.hasElse) THEN > > Marker.PushTryElse (l, l+1, frame); > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > Thanks, > > - Jay > > > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >> > >>> > >>> I believe you can, but it'd take significant work in the frontend. > >>> The jmpbuf should identify merely which procedure/frame to return to. > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>> Instead of setjmp, the compiler pessimizes appropriately. > >>> > >>> > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>> where in the function it is. > >>> > >>> > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>> > >>> > >>> It is more work through, granted, I can understand that. > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>> > >>> > >>> Anyway, I'm trying what you say, like for TRY within a loop. > >>> > >>> > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>> It aligns more. So it is using more stack than the other way. > >>> And it might pessimize codegen in other ways. > >>> > >>> > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>> function/frame to return to, and that within the frame there is a local integer to determine > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>> > >>> > >>> - Jay > >>> > >>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>> since they can be nested. > >>>> > >>>> > >>>> > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>> > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>> local "EF1" for each try. > >>>> I guess, really, it is EF1, EF2, etc. > >>>> So there should be a separate local for the jmpbuf pointer, and store > >>>> it in each EF* block? > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>> to in the front end, I need to read it more. > >>>> > >>>> something like: > >>>> > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>> END END END END F1; > >>>> => > >>>> > >>>> void F1() > >>>> { > >>>> jmp_buf* jb = 0; > >>>> EF1 a,b,c; > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>> do stuff 1... > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>> do stuff 2... > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>> do stuff 3... > >>>> } > >>>> > >>>> (The actual syntactic and semantic correctness of this code -- the > >>>> existance of the ternary operator, and that it only evaluates one side > >>>> or the other, and that assignment is expression..I quite like those > >>>> features....) > >>>> > >>>> > >>>> Still, something I can't pin down strikes me as too simple here. > >>>> > >>>> > >>>> If there is just one setjmp, and no integer(s) to keep track of > >>>> additional progress, you only ever know the last place you were in a > >>>> function. > >>>> That doesn't seem adequate. > >>>> > >>>> > >>>> What if a function raises an exception, catches it within itself, and > >>>> then raises something else, and then wants to catch that? > >>>> It won't know where to resume, right? It's just keep longjmping to the > >>>> same place. > >>>> > >>>> > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>> across functions. > >>>> I think somehow that is related here. > >>>> > >>>> > >>>> e.g. how would you ensure forward progress in this: > >>>> > >>>> > >>>> EXCEPTION E1; > >>>> EXCEPTION E2; > >>>> EXCEPTION E3; > >>>> > >>>> > >>>> PROCEDURE F4() RAISES ANY = > >>>> CONST Function = "F4 "; > >>>> BEGIN > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> RAISE E1; > >>>> EXCEPT ELSE > >>>> RAISE E2; > >>>> END; > >>>> EXCEPT ELSE > >>>> RAISE E3; > >>>> END; > >>>> EXCEPT ELSE > >>>> END; > >>>> END F4; > >>>> > >>>> > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> I am OK with what you have currently: > >>>> > >>>> At each TRY: > >>>> > >>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>> if the corresponding local variable is NIL. > >>>> 2. If not, then alloca and save its pointer in the local variable > >>>> 3. Execute the try block. > >>>> > >>>> As you say, alloca should turn into an inline operation using the > >>>> compiler's builtin implementation of alloca. > >>>> > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>> > >>>>> Code size will suffer. > >>>> > >>>> > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>> I thought it'd only be one call. I didn't realize our implementation > >>>> is as poor as it is, since a better but still > >>>> portable implementation doesn't seem too too difficult. > >>>> > >>>> > >>>> Can we maybe do the optimizations I indicate -- no more than one > >>>> setjmp/alloca/pushframe per function? > >>>> Using a local integer to record the position within the function? > >>>> > >>>> > >>>> Or just give me a week or few to get stack walking working and then > >>>> live the regression on other targets? > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>> possible; NT does have a decent runtime here..) > >>>> > >>>> > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>> > >>>> > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>> It doesn't work for intra-function jumps, only inter-function. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>> > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>> point is, you'd rather have n locals, which the backend automatically > >>>> merges, than n calls to alloca? > >>>> It's not a huge difference -- there are still going to be n calls to > >>>> setjmp and n calls to pthread_getspecific. > >>>> The alloca calls will be dwarfed. > >>>> Code size will suffer. > >>>> > >>>> > >>>> And, even so, there are plenty of optimizations to be had, even if > >>>> setjmp/pthread_getspecific is used. > >>>> > >>>> > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>> per function > >>>> - The calls to alloca could be merged. The frontend could keep track > >>>> of how many calls it makes per function, > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>> > >>>> > >>>> So, yes, given my current understanding, it is progress. > >>>> The target-dependence is not worth it, imho. > >>>> I'll still do some comparisons to release. > >>>> > >>>> > >>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>> > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>> I'll do more testing. > >>>> > >>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>> > >>>> > >>>> So the additional inefficiency is multiplied the same as the rest of > >>>> the preexisting inefficiency. > >>>> And the preexisting inefficiency is way more than the increase. > >>>> > >>>> And second, either way, it could be better. > >>>> > >>>> Basically, the model should be, that if a function has any try or lock, > >>>> it calls setjmp once. > >>>> And then, it should have one volatile integer, that in a sense > >>>> represents the line number. > >>>> But not really. It's like, every time you cross a TRY, the integer is > >>>> incremented, every time you > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>> value can be stored. > >>>> And then there is a maximum of one one handler per function, it > >>>> switches on the integer > >>>> to decide where it got into the function and what it should do. > >>>> > >>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Note that you need a different jmpbuf for each nested TRY! > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>> > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>> it -- check for NIL. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>> are allocating on every TRY where previously the storage was statically > >>>> allocated. Do you really think this is progress? > >>>> > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>> > >>>> I've back with full keyboard if more explanation needed. The diff is > >>>> actually fairly small to read. > >>>> I understand it is definitely less efficient, a few more instructions > >>>> for every try/lock. > >>>> No extra function call, at least with gcc backend. > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>> is written so that it should work > >>>> but I have to test it to be sure, will to roughly tonight. And there > >>>> probably is a function call there. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>> CC: m3commit at elegosoft.com > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>> definitely a bit less efficient, but the significant advantage is > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>> > >>>> > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>> the problem is addressed there. > >>>> > >>>> > >>>> The inefficiency of course can be dramatically mitigated via a stack > >>>> walker. I wanted to do this first though, while more targets using > >>>> setjmp. > >>>> > >>>> - Jay/phone > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Can you provide a more descriptive checkin comment? I don't know what > >>>> has been done here without diving into the diff. > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>> > >>>> diff attached > >>>> > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>> To: m3commit at elegosoft.com > >>>>> From: jkrell at elego.de > >>>>> Subject: [M3commit] CVS Update: cm3 > >>>>> > >>>>> CVSROOT: /usr/cvs > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>> > >>>>> Modified files: > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>> > >>>>> Log message: > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>> > >>>>> to allocate jmp_buf > >>>>> > >>>>> - eliminates a large swath of target-dependent code > >>>>> - allows for covering up the inability to declare > >>>>> types with alignment > 64 bits > >>>>> > >>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>> > >> > > > From jay.krell at cornell.edu Thu Jan 6 21:51:58 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:51:58 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: ps: I think there other non-ideal initializations here. e.g. TryFinStmt.m3:Compile2 ??? (* declare and initialize the info record *) ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_procedure (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_handler); ??? CG.Load_static_link (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_frame); Putting TRY/LOCK in loops probably repeatedly does the same initializations. Granted, this is non-stack-walker code. Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. ?- Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 20:48:56 +0000 > > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 15:42:33 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > I don't understand what you mean by "initializes to NIL". > > How are you creating the frame variable? > > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > > > > Ok. > > > Do you know where to initialize the jmpbuf to NIL? > > > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > > it checks for NIL and branches around the alloca for non-NIL, but it > > > also initializes to NIL repeatedly, so no change effectively. > > > > > > > > > Index: misc/Marker.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > > retrieving revision 1.7 > > > diff -u -w -r1.7 Marker.m3 > > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -233,6 +233,7 @@ > > > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > > VAR new: BOOLEAN; > > > + label := CG.Next_label (); > > > BEGIN > > > (* int setjmp(void* ); *) > > > IF (setjmp = NIL) THEN > > > @@ -263,18 +264,25 @@ > > > Target.Word.cg_type, 0); > > > END; > > > > > > + (* IF frame.jmpbuf = NIL THEN *) > > > + > > > + CG.Load_nil (); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > > + > > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > > CG.Pop_param (Target.Word.cg_type); > > > CG.Call_direct (alloca, Target.Address.cg_type); > > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > + (* END *) > > > + CG.Set_label (label); > > > > > > (* setmp(frame.jmpbuf) *) > > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > CG.Pop_param (CG.Type.Addr); > > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > > CG.If_true (handler, CG.Never); > > > cvs diff: Diffing stmts > > > Index: stmts/TryFinStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > > retrieving revision 1.6 > > > diff -u -w -r1.6 TryFinStmt.m3 > > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -299,6 +299,10 @@ > > > CG.Load_nil (); > > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > l := CG.Next_label (3); > > > CG.Set_label (l, barrier := TRUE); > > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > > Index: stmts/TryStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > > retrieving revision 1.3 > > > diff -u -w -r1.3 TryStmt.m3 > > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -10,7 +10,7 @@ > > > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > > > TYPE > > > @@ -411,6 +411,10 @@ > > > CG.Store_addr (frame, M3RT.EF1_exception); > > > ***********************************************) > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > IF (p.hasElse) THEN > > > Marker.PushTryElse (l, l+1, frame); > > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > > > Thanks, > > > - Jay > > > > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >> > > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >> 305 N. University Street | West Lafayette | IN 47907 | USA > > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >> > > >> > > >> > > >> > > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >> > > >>> > > >>> I believe you can, but it'd take significant work in the frontend. > > >>> The jmpbuf should identify merely which procedure/frame to return to. > > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>> Instead of setjmp, the compiler pessimizes appropriately. > > >>> > > >>> > > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>> where in the function it is. > > >>> > > >>> > > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>> > > >>> > > >>> It is more work through, granted, I can understand that. > > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>> > > >>> > > >>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>> > > >>> > > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>> It aligns more. So it is using more stack than the other way. > > >>> And it might pessimize codegen in other ways. > > >>> > > >>> > > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>> function/frame to return to, and that within the frame there is a local integer to determine > > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>> > > >>> > > >>> - Jay > > >>> > > >>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>> since they can be nested. > > >>>> > > >>>> > > >>>> > > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>> > > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>> local "EF1" for each try. > > >>>> I guess, really, it is EF1, EF2, etc. > > >>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>> it in each EF* block? > > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>> to in the front end, I need to read it more. > > >>>> > > >>>> something like: > > >>>> > > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>> END END END END F1; > > >>>> => > > >>>> > > >>>> void F1() > > >>>> { > > >>>> jmp_buf* jb = 0; > > >>>> EF1 a,b,c; > > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>> do stuff 1... > > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>> do stuff 2... > > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>> do stuff 3... > > >>>> } > > >>>> > > >>>> (The actual syntactic and semantic correctness of this code -- the > > >>>> existance of the ternary operator, and that it only evaluates one side > > >>>> or the other, and that assignment is expression..I quite like those > > >>>> features....) > > >>>> > > >>>> > > >>>> Still, something I can't pin down strikes me as too simple here. > > >>>> > > >>>> > > >>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>> additional progress, you only ever know the last place you were in a > > >>>> function. > > >>>> That doesn't seem adequate. > > >>>> > > >>>> > > >>>> What if a function raises an exception, catches it within itself, and > > >>>> then raises something else, and then wants to catch that? > > >>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>> same place. > > >>>> > > >>>> > > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>> across functions. > > >>>> I think somehow that is related here. > > >>>> > > >>>> > > >>>> e.g. how would you ensure forward progress in this: > > >>>> > > >>>> > > >>>> EXCEPTION E1; > > >>>> EXCEPTION E2; > > >>>> EXCEPTION E3; > > >>>> > > >>>> > > >>>> PROCEDURE F4() RAISES ANY = > > >>>> CONST Function = "F4 "; > > >>>> BEGIN > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> RAISE E1; > > >>>> EXCEPT ELSE > > >>>> RAISE E2; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> RAISE E3; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> END; > > >>>> END F4; > > >>>> > > >>>> > > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> I am OK with what you have currently: > > >>>> > > >>>> At each TRY: > > >>>> > > >>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>> if the corresponding local variable is NIL. > > >>>> 2. If not, then alloca and save its pointer in the local variable > > >>>> 3. Execute the try block. > > >>>> > > >>>> As you say, alloca should turn into an inline operation using the > > >>>> compiler's builtin implementation of alloca. > > >>>> > > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>> > > >>>>> Code size will suffer. > > >>>> > > >>>> > > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>> I thought it'd only be one call. I didn't realize our implementation > > >>>> is as poor as it is, since a better but still > > >>>> portable implementation doesn't seem too too difficult. > > >>>> > > >>>> > > >>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>> setjmp/alloca/pushframe per function? > > >>>> Using a local integer to record the position within the function? > > >>>> > > >>>> > > >>>> Or just give me a week or few to get stack walking working and then > > >>>> live the regression on other targets? > > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>> possible; NT does have a decent runtime here..) > > >>>> > > >>>> > > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>> > > >>>> > > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>> It doesn't work for intra-function jumps, only inter-function. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>> > > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>> point is, you'd rather have n locals, which the backend automatically > > >>>> merges, than n calls to alloca? > > >>>> It's not a huge difference -- there are still going to be n calls to > > >>>> setjmp and n calls to pthread_getspecific. > > >>>> The alloca calls will be dwarfed. > > >>>> Code size will suffer. > > >>>> > > >>>> > > >>>> And, even so, there are plenty of optimizations to be had, even if > > >>>> setjmp/pthread_getspecific is used. > > >>>> > > >>>> > > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>> per function > > >>>> - The calls to alloca could be merged. The frontend could keep track > > >>>> of how many calls it makes per function, > > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>> > > >>>> > > >>>> So, yes, given my current understanding, it is progress. > > >>>> The target-dependence is not worth it, imho. > > >>>> I'll still do some comparisons to release. > > >>>> > > >>>> > > >>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>> > > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>> I'll do more testing. > > >>>> > > >>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>> > > >>>> > > >>>> So the additional inefficiency is multiplied the same as the rest of > > >>>> the preexisting inefficiency. > > >>>> And the preexisting inefficiency is way more than the increase. > > >>>> > > >>>> And second, either way, it could be better. > > >>>> > > >>>> Basically, the model should be, that if a function has any try or lock, > > >>>> it calls setjmp once. > > >>>> And then, it should have one volatile integer, that in a sense > > >>>> represents the line number. > > >>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>> incremented, every time you > > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>> value can be stored. > > >>>> And then there is a maximum of one one handler per function, it > > >>>> switches on the integer > > >>>> to decide where it got into the function and what it should do. > > >>>> > > >>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Note that you need a different jmpbuf for each nested TRY! > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>> > > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>> it -- check for NIL. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>> are allocating on every TRY where previously the storage was statically > > >>>> allocated. Do you really think this is progress? > > >>>> > > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>> > > >>>> I've back with full keyboard if more explanation needed. The diff is > > >>>> actually fairly small to read. > > >>>> I understand it is definitely less efficient, a few more instructions > > >>>> for every try/lock. > > >>>> No extra function call, at least with gcc backend. > > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>> is written so that it should work > > >>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>> probably is a function call there. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> > > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>> definitely a bit less efficient, but the significant advantage is > > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>> > > >>>> > > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>> the problem is addressed there. > > >>>> > > >>>> > > >>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>> walker. I wanted to do this first though, while more targets using > > >>>> setjmp. > > >>>> > > >>>> - Jay/phone > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>> has been done here without diving into the diff. > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>> > > >>>> diff attached > > >>>> > > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>> To: m3commit at elegosoft.com > > >>>>> From: jkrell at elego.de > > >>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>> > > >>>>> CVSROOT: /usr/cvs > > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>> > > >>>>> Modified files: > > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>> > > >>>>> Log message: > > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>> > > >>>>> to allocate jmp_buf > > >>>>> > > >>>>> - eliminates a large swath of target-dependent code > > >>>>> - allows for covering up the inability to declare > > >>>>> types with alignment > 64 bits > > >>>>> > > >>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Thu Jan 6 21:58:54 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:58:54 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: What you want to do is use the "variable" slot in the frame to hold a variable for TRY frames, similarly to PROC frames. Then it will be initialized correctly. You should give it type Addr.T. On Jan 6, 2011, at 3:48 PM, Jay K wrote: > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 15:42:33 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I don't understand what you mean by "initializes to NIL". >> How are you creating the frame variable? >> If you do it properly the language semantics will cause it be initialized to NIL automatically. >> >> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >> >>> >>> Ok. >>> Do you know where to initialize the jmpbuf to NIL? >>> >>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>> it checks for NIL and branches around the alloca for non-NIL, but it >>> also initializes to NIL repeatedly, so no change effectively. >>> >>> >>> Index: misc/Marker.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>> retrieving revision 1.7 >>> diff -u -w -r1.7 Marker.m3 >>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -233,6 +233,7 @@ >>> >>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>> VAR new: BOOLEAN; >>> + label := CG.Next_label (); >>> BEGIN >>> (* int setjmp(void* ); *) >>> IF (setjmp = NIL) THEN >>> @@ -263,18 +264,25 @@ >>> Target.Word.cg_type, 0); >>> END; >>> >>> + (* IF frame.jmpbuf = NIL THEN *) >>> + >>> + CG.Load_nil (); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>> + >>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>> CG.Pop_param (Target.Word.cg_type); >>> CG.Call_direct (alloca, Target.Address.cg_type); >>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> + (* END *) >>> + CG.Set_label (label); >>> >>> (* setmp(frame.jmpbuf) *) >>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> CG.Pop_param (CG.Type.Addr); >>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>> CG.If_true (handler, CG.Never); >>> cvs diff: Diffing stmts >>> Index: stmts/TryFinStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>> retrieving revision 1.6 >>> diff -u -w -r1.6 TryFinStmt.m3 >>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -299,6 +299,10 @@ >>> CG.Load_nil (); >>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> l := CG.Next_label (3); >>> CG.Set_label (l, barrier := TRUE); >>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>> Index: stmts/TryStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>> retrieving revision 1.3 >>> diff -u -w -r1.3 TryStmt.m3 >>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -10,7 +10,7 @@ >>> >>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>> >>> TYPE >>> @@ -411,6 +411,10 @@ >>> CG.Store_addr (frame, M3RT.EF1_exception); >>> ***********************************************) >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> IF (p.hasElse) THEN >>> Marker.PushTryElse (l, l+1, frame); >>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>> >>> >>> The set_label before one of the PushEFrames could be moved down a bit, >>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>> >>> Thanks, >>> - Jay >>> >>> >>> ---------------------------------------- >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>> >>>>> >>>>> I believe you can, but it'd take significant work in the frontend. >>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>> >>>>> >>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>> where in the function it is. >>>>> >>>>> >>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>> >>>>> >>>>> It is more work through, granted, I can understand that. >>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>> >>>>> >>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>> >>>>> >>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>> It aligns more. So it is using more stack than the other way. >>>>> And it might pessimize codegen in other ways. >>>>> >>>>> >>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>> >>>>> >>>>> - Jay >>>>> >>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>> since they can be nested. >>>>>> >>>>>> >>>>>> >>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>> >>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>> local "EF1" for each try. >>>>>> I guess, really, it is EF1, EF2, etc. >>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>> it in each EF* block? >>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>> to in the front end, I need to read it more. >>>>>> >>>>>> something like: >>>>>> >>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>> END END END END F1; >>>>>> => >>>>>> >>>>>> void F1() >>>>>> { >>>>>> jmp_buf* jb = 0; >>>>>> EF1 a,b,c; >>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>> do stuff 1... >>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>> do stuff 2... >>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>> do stuff 3... >>>>>> } >>>>>> >>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>> or the other, and that assignment is expression..I quite like those >>>>>> features....) >>>>>> >>>>>> >>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>> >>>>>> >>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>> additional progress, you only ever know the last place you were in a >>>>>> function. >>>>>> That doesn't seem adequate. >>>>>> >>>>>> >>>>>> What if a function raises an exception, catches it within itself, and >>>>>> then raises something else, and then wants to catch that? >>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>> same place. >>>>>> >>>>>> >>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>> across functions. >>>>>> I think somehow that is related here. >>>>>> >>>>>> >>>>>> e.g. how would you ensure forward progress in this: >>>>>> >>>>>> >>>>>> EXCEPTION E1; >>>>>> EXCEPTION E2; >>>>>> EXCEPTION E3; >>>>>> >>>>>> >>>>>> PROCEDURE F4() RAISES ANY = >>>>>> CONST Function = "F4 "; >>>>>> BEGIN >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> RAISE E1; >>>>>> EXCEPT ELSE >>>>>> RAISE E2; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> RAISE E3; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> END; >>>>>> END F4; >>>>>> >>>>>> >>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> I am OK with what you have currently: >>>>>> >>>>>> At each TRY: >>>>>> >>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>> if the corresponding local variable is NIL. >>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>> 3. Execute the try block. >>>>>> >>>>>> As you say, alloca should turn into an inline operation using the >>>>>> compiler's builtin implementation of alloca. >>>>>> >>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>> >>>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>> is as poor as it is, since a better but still >>>>>> portable implementation doesn't seem too too difficult. >>>>>> >>>>>> >>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>> setjmp/alloca/pushframe per function? >>>>>> Using a local integer to record the position within the function? >>>>>> >>>>>> >>>>>> Or just give me a week or few to get stack walking working and then >>>>>> live the regression on other targets? >>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>> possible; NT does have a decent runtime here..) >>>>>> >>>>>> >>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>> >>>>>> >>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>> >>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>> merges, than n calls to alloca? >>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>> setjmp and n calls to pthread_getspecific. >>>>>> The alloca calls will be dwarfed. >>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>> setjmp/pthread_getspecific is used. >>>>>> >>>>>> >>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>> per function >>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>> of how many calls it makes per function, >>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>> >>>>>> >>>>>> So, yes, given my current understanding, it is progress. >>>>>> The target-dependence is not worth it, imho. >>>>>> I'll still do some comparisons to release. >>>>>> >>>>>> >>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>> >>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>> I'll do more testing. >>>>>> >>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>> >>>>>> >>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>> the preexisting inefficiency. >>>>>> And the preexisting inefficiency is way more than the increase. >>>>>> >>>>>> And second, either way, it could be better. >>>>>> >>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>> it calls setjmp once. >>>>>> And then, it should have one volatile integer, that in a sense >>>>>> represents the line number. >>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>> incremented, every time you >>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>> value can be stored. >>>>>> And then there is a maximum of one one handler per function, it >>>>>> switches on the integer >>>>>> to decide where it got into the function and what it should do. >>>>>> >>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>> >>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>> it -- check for NIL. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>> are allocating on every TRY where previously the storage was statically >>>>>> allocated. Do you really think this is progress? >>>>>> >>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>> >>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>> actually fairly small to read. >>>>>> I understand it is definitely less efficient, a few more instructions >>>>>> for every try/lock. >>>>>> No extra function call, at least with gcc backend. >>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>> is written so that it should work >>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>> probably is a function call there. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> >>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>> definitely a bit less efficient, but the significant advantage is >>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>> >>>>>> >>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>> the problem is addressed there. >>>>>> >>>>>> >>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>> walker. I wanted to do this first though, while more targets using >>>>>> setjmp. >>>>>> >>>>>> - Jay/phone >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>> has been done here without diving into the diff. >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>> >>>>>> diff attached >>>>>> >>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>> To: m3commit at elegosoft.com >>>>>>> From: jkrell at elego.de >>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> CVSROOT: /usr/cvs >>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>> >>>>>>> Modified files: >>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>> >>>>>>> Log message: >>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>> >>>>>>> to allocate jmp_buf >>>>>>> >>>>>>> - eliminates a large swath of target-dependent code >>>>>>> - allows for covering up the inability to declare >>>>>>> types with alignment > 64 bits >>>>>>> >>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> > From hosking at cs.purdue.edu Thu Jan 6 22:00:08 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:00:08 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: In the code below there are no initializations. On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > ps: I think there other non-ideal initializations here. > e.g. > > > TryFinStmt.m3:Compile2 > (* declare and initialize the info record *) > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_procedure (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_handler); > CG.Load_static_link (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_frame); > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > Granted, this is non-stack-walker code. > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > - Jay > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 20:48:56 +0000 >> >> >> The same way as before. I think this operates at too low a level to get any automatic initialization. >> >> TryStmt.m3 and TryFinStmt.m3: >> >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >> CG.Type.Struct, 0, in_memory := TRUE, >> up_level := FALSE, f := CG.Never); >> >> I agree though, this might not be ideal. >> >> - Jay >> >> >> ---------------------------------------- >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> I don't understand what you mean by "initializes to NIL". >>> How are you creating the frame variable? >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>> >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>> >>>> >>>> Ok. >>>> Do you know where to initialize the jmpbuf to NIL? >>>> >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>> also initializes to NIL repeatedly, so no change effectively. >>>> >>>> >>>> Index: misc/Marker.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>> retrieving revision 1.7 >>>> diff -u -w -r1.7 Marker.m3 >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -233,6 +233,7 @@ >>>> >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>> VAR new: BOOLEAN; >>>> + label := CG.Next_label (); >>>> BEGIN >>>> (* int setjmp(void* ); *) >>>> IF (setjmp = NIL) THEN >>>> @@ -263,18 +264,25 @@ >>>> Target.Word.cg_type, 0); >>>> END; >>>> >>>> + (* IF frame.jmpbuf = NIL THEN *) >>>> + >>>> + CG.Load_nil (); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>> + >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>> CG.Pop_param (Target.Word.cg_type); >>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> + (* END *) >>>> + CG.Set_label (label); >>>> >>>> (* setmp(frame.jmpbuf) *) >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> CG.Pop_param (CG.Type.Addr); >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>> CG.If_true (handler, CG.Never); >>>> cvs diff: Diffing stmts >>>> Index: stmts/TryFinStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>> retrieving revision 1.6 >>>> diff -u -w -r1.6 TryFinStmt.m3 >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -299,6 +299,10 @@ >>>> CG.Load_nil (); >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> l := CG.Next_label (3); >>>> CG.Set_label (l, barrier := TRUE); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>> Index: stmts/TryStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>> retrieving revision 1.3 >>>> diff -u -w -r1.3 TryStmt.m3 >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -10,7 +10,7 @@ >>>> >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>> >>>> TYPE >>>> @@ -411,6 +411,10 @@ >>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>> ***********************************************) >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> IF (p.hasElse) THEN >>>> Marker.PushTryElse (l, l+1, frame); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>> >>>> >>>> The set_label before one of the PushEFrames could be moved down a bit, >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>> >>>> Thanks, >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>> >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>> >>>>> >>>>> >>>>> >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>> >>>>>> >>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>> >>>>>> >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>> where in the function it is. >>>>>> >>>>>> >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>> >>>>>> >>>>>> It is more work through, granted, I can understand that. >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>> >>>>>> >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>> >>>>>> >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>> It aligns more. So it is using more stack than the other way. >>>>>> And it might pessimize codegen in other ways. >>>>>> >>>>>> >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>> since they can be nested. >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>> >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>> local "EF1" for each try. >>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>> it in each EF* block? >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>> to in the front end, I need to read it more. >>>>>>> >>>>>>> something like: >>>>>>> >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>> END END END END F1; >>>>>>> => >>>>>>> >>>>>>> void F1() >>>>>>> { >>>>>>> jmp_buf* jb = 0; >>>>>>> EF1 a,b,c; >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>> do stuff 1... >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>> do stuff 2... >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>> do stuff 3... >>>>>>> } >>>>>>> >>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>> features....) >>>>>>> >>>>>>> >>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>> >>>>>>> >>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>> additional progress, you only ever know the last place you were in a >>>>>>> function. >>>>>>> That doesn't seem adequate. >>>>>>> >>>>>>> >>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>> then raises something else, and then wants to catch that? >>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>> same place. >>>>>>> >>>>>>> >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>> across functions. >>>>>>> I think somehow that is related here. >>>>>>> >>>>>>> >>>>>>> e.g. how would you ensure forward progress in this: >>>>>>> >>>>>>> >>>>>>> EXCEPTION E1; >>>>>>> EXCEPTION E2; >>>>>>> EXCEPTION E3; >>>>>>> >>>>>>> >>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>> CONST Function = "F4 "; >>>>>>> BEGIN >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> RAISE E1; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E2; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E3; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> END; >>>>>>> END F4; >>>>>>> >>>>>>> >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> I am OK with what you have currently: >>>>>>> >>>>>>> At each TRY: >>>>>>> >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>> if the corresponding local variable is NIL. >>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>> 3. Execute the try block. >>>>>>> >>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>> compiler's builtin implementation of alloca. >>>>>>> >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>> >>>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>> is as poor as it is, since a better but still >>>>>>> portable implementation doesn't seem too too difficult. >>>>>>> >>>>>>> >>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>> setjmp/alloca/pushframe per function? >>>>>>> Using a local integer to record the position within the function? >>>>>>> >>>>>>> >>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>> live the regression on other targets? >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>> possible; NT does have a decent runtime here..) >>>>>>> >>>>>>> >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>> >>>>>>> >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>> >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>> merges, than n calls to alloca? >>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>> The alloca calls will be dwarfed. >>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>> setjmp/pthread_getspecific is used. >>>>>>> >>>>>>> >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>> per function >>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>> of how many calls it makes per function, >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>> >>>>>>> >>>>>>> So, yes, given my current understanding, it is progress. >>>>>>> The target-dependence is not worth it, imho. >>>>>>> I'll still do some comparisons to release. >>>>>>> >>>>>>> >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>> >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>> I'll do more testing. >>>>>>> >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>> >>>>>>> >>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>> the preexisting inefficiency. >>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>> >>>>>>> And second, either way, it could be better. >>>>>>> >>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>> it calls setjmp once. >>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>> represents the line number. >>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>> incremented, every time you >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>> value can be stored. >>>>>>> And then there is a maximum of one one handler per function, it >>>>>>> switches on the integer >>>>>>> to decide where it got into the function and what it should do. >>>>>>> >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>> >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>> it -- check for NIL. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>> allocated. Do you really think this is progress? >>>>>>> >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>> >>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>> actually fairly small to read. >>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>> for every try/lock. >>>>>>> No extra function call, at least with gcc backend. >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>> is written so that it should work >>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>> probably is a function call there. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>> >>>>>>> >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>> the problem is addressed there. >>>>>>> >>>>>>> >>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>> setjmp. >>>>>>> >>>>>>> - Jay/phone >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>> has been done here without diving into the diff. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>> >>>>>>> diff attached >>>>>>> >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>> To: m3commit at elegosoft.com >>>>>>>> From: jkrell at elego.de >>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>> >>>>>>>> CVSROOT: /usr/cvs >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>> >>>>>>>> Modified files: >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>> >>>>>>>> Log message: >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>> >>>>>>>> to allocate jmp_buf >>>>>>>> >>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>> - allows for covering up the inability to declare >>>>>>>> types with alignment > 64 bits >>>>>>>> >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 22:17:03 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 21:17:03 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:00:08 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > In the code below there are no initializations. > > On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > > > > ps: I think there other non-ideal initializations here. > > e.g. > > > > > > TryFinStmt.m3:Compile2 > > (* declare and initialize the info record *) > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_procedure (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_handler); > > CG.Load_static_link (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_frame); > > > > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > Granted, this is non-stack-walker code. > > > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > > > - Jay > > > > ---------------------------------------- > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >> > >> > >> The same way as before. I think this operates at too low a level to get any automatic initialization. > >> > >> TryStmt.m3 and TryFinStmt.m3: > >> > >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >> CG.Type.Struct, 0, in_memory := TRUE, > >> up_level := FALSE, f := CG.Never); > >> > >> I agree though, this might not be ideal. > >> > >> - Jay > >> > >> > >> ---------------------------------------- > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> I don't understand what you mean by "initializes to NIL". > >>> How are you creating the frame variable? > >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>> > >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>> > >>>> > >>>> Ok. > >>>> Do you know where to initialize the jmpbuf to NIL? > >>>> > >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>> also initializes to NIL repeatedly, so no change effectively. > >>>> > >>>> > >>>> Index: misc/Marker.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>> retrieving revision 1.7 > >>>> diff -u -w -r1.7 Marker.m3 > >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -233,6 +233,7 @@ > >>>> > >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>> VAR new: BOOLEAN; > >>>> + label := CG.Next_label (); > >>>> BEGIN > >>>> (* int setjmp(void* ); *) > >>>> IF (setjmp = NIL) THEN > >>>> @@ -263,18 +264,25 @@ > >>>> Target.Word.cg_type, 0); > >>>> END; > >>>> > >>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>> + > >>>> + CG.Load_nil (); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>> + > >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>> CG.Pop_param (Target.Word.cg_type); > >>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> + (* END *) > >>>> + CG.Set_label (label); > >>>> > >>>> (* setmp(frame.jmpbuf) *) > >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> CG.Pop_param (CG.Type.Addr); > >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>> CG.If_true (handler, CG.Never); > >>>> cvs diff: Diffing stmts > >>>> Index: stmts/TryFinStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>> retrieving revision 1.6 > >>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -299,6 +299,10 @@ > >>>> CG.Load_nil (); > >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> l := CG.Next_label (3); > >>>> CG.Set_label (l, barrier := TRUE); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>> Index: stmts/TryStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>> retrieving revision 1.3 > >>>> diff -u -w -r1.3 TryStmt.m3 > >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -10,7 +10,7 @@ > >>>> > >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>> > >>>> TYPE > >>>> @@ -411,6 +411,10 @@ > >>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>> ***********************************************) > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> IF (p.hasElse) THEN > >>>> Marker.PushTryElse (l, l+1, frame); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>> > >>>> > >>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>> > >>>> Thanks, > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>> > >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>> > >>>>>> > >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>> where in the function it is. > >>>>>> > >>>>>> > >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>> > >>>>>> > >>>>>> It is more work through, granted, I can understand that. > >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>> > >>>>>> > >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>> > >>>>>> > >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>> It aligns more. So it is using more stack than the other way. > >>>>>> And it might pessimize codegen in other ways. > >>>>>> > >>>>>> > >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>> > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>> since they can be nested. > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>> > >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>> local "EF1" for each try. > >>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>> it in each EF* block? > >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>> to in the front end, I need to read it more. > >>>>>>> > >>>>>>> something like: > >>>>>>> > >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>> END END END END F1; > >>>>>>> => > >>>>>>> > >>>>>>> void F1() > >>>>>>> { > >>>>>>> jmp_buf* jb = 0; > >>>>>>> EF1 a,b,c; > >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>> do stuff 1... > >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>> do stuff 2... > >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>> do stuff 3... > >>>>>>> } > >>>>>>> > >>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>> features....) > >>>>>>> > >>>>>>> > >>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>> > >>>>>>> > >>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>> function. > >>>>>>> That doesn't seem adequate. > >>>>>>> > >>>>>>> > >>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>> then raises something else, and then wants to catch that? > >>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>> same place. > >>>>>>> > >>>>>>> > >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>> across functions. > >>>>>>> I think somehow that is related here. > >>>>>>> > >>>>>>> > >>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>> > >>>>>>> > >>>>>>> EXCEPTION E1; > >>>>>>> EXCEPTION E2; > >>>>>>> EXCEPTION E3; > >>>>>>> > >>>>>>> > >>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>> CONST Function = "F4 "; > >>>>>>> BEGIN > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> RAISE E1; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E2; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E3; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> END; > >>>>>>> END F4; > >>>>>>> > >>>>>>> > >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> I am OK with what you have currently: > >>>>>>> > >>>>>>> At each TRY: > >>>>>>> > >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>> if the corresponding local variable is NIL. > >>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>> 3. Execute the try block. > >>>>>>> > >>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>> compiler's builtin implementation of alloca. > >>>>>>> > >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>> > >>>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>> is as poor as it is, since a better but still > >>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>> > >>>>>>> > >>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>> setjmp/alloca/pushframe per function? > >>>>>>> Using a local integer to record the position within the function? > >>>>>>> > >>>>>>> > >>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>> live the regression on other targets? > >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>> possible; NT does have a decent runtime here..) > >>>>>>> > >>>>>>> > >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>> > >>>>>>> > >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>> > >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>> merges, than n calls to alloca? > >>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>> The alloca calls will be dwarfed. > >>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>> setjmp/pthread_getspecific is used. > >>>>>>> > >>>>>>> > >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>> per function > >>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>> of how many calls it makes per function, > >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>> > >>>>>>> > >>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>> The target-dependence is not worth it, imho. > >>>>>>> I'll still do some comparisons to release. > >>>>>>> > >>>>>>> > >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>> > >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>> I'll do more testing. > >>>>>>> > >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>> > >>>>>>> > >>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>> the preexisting inefficiency. > >>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>> > >>>>>>> And second, either way, it could be better. > >>>>>>> > >>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>> it calls setjmp once. > >>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>> represents the line number. > >>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>> incremented, every time you > >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>> value can be stored. > >>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>> switches on the integer > >>>>>>> to decide where it got into the function and what it should do. > >>>>>>> > >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>> > >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>> it -- check for NIL. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>> allocated. Do you really think this is progress? > >>>>>>> > >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>> > >>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>> actually fairly small to read. > >>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>> for every try/lock. > >>>>>>> No extra function call, at least with gcc backend. > >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>> is written so that it should work > >>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>> probably is a function call there. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> > >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>> > >>>>>>> > >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>> the problem is addressed there. > >>>>>>> > >>>>>>> > >>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>> setjmp. > >>>>>>> > >>>>>>> - Jay/phone > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>> has been done here without diving into the diff. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>> > >>>>>>> diff attached > >>>>>>> > >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>> To: m3commit at elegosoft.com > >>>>>>>> From: jkrell at elego.de > >>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>> > >>>>>>>> CVSROOT: /usr/cvs > >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>> > >>>>>>>> Modified files: > >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>> > >>>>>>>> Log message: > >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>> > >>>>>>>> to allocate jmp_buf > >>>>>>>> > >>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>> - allows for covering up the inability to declare > >>>>>>>> types with alignment > 64 bits > >>>>>>>> > >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > From hosking at cs.purdue.edu Thu Jan 6 22:56:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:56:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> You are confusing code emitted in the body of the loop with dynamic executions of that code. CG calls are all compile-time generation of code. On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > - Jay > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 16:00:08 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> In the code below there are no initializations. >> >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >> >>> >>> ps: I think there other non-ideal initializations here. >>> e.g. >>> >>> >>> TryFinStmt.m3:Compile2 >>> (* declare and initialize the info record *) >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, >>> CG.Type.Struct, 0, in_memory := TRUE, >>> up_level := FALSE, f := CG.Never); >>> CG.Load_procedure (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_handler); >>> CG.Load_static_link (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_frame); >>> >>> >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. >>> Granted, this is non-stack-walker code. >>> >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. >>> >>> - Jay >>> >>> ---------------------------------------- >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>> >>>> >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. >>>> >>>> TryStmt.m3 and TryFinStmt.m3: >>>> >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >>>> CG.Type.Struct, 0, in_memory := TRUE, >>>> up_level := FALSE, f := CG.Never); >>>> >>>> I agree though, this might not be ideal. >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> I don't understand what you mean by "initializes to NIL". >>>>> How are you creating the frame variable? >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>>>> >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>> >>>>>> >>>>>> Ok. >>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>> >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>> >>>>>> >>>>>> Index: misc/Marker.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>> retrieving revision 1.7 >>>>>> diff -u -w -r1.7 Marker.m3 >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -233,6 +233,7 @@ >>>>>> >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>> VAR new: BOOLEAN; >>>>>> + label := CG.Next_label (); >>>>>> BEGIN >>>>>> (* int setjmp(void* ); *) >>>>>> IF (setjmp = NIL) THEN >>>>>> @@ -263,18 +264,25 @@ >>>>>> Target.Word.cg_type, 0); >>>>>> END; >>>>>> >>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>> + >>>>>> + CG.Load_nil (); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>>>> + >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> + (* END *) >>>>>> + CG.Set_label (label); >>>>>> >>>>>> (* setmp(frame.jmpbuf) *) >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> CG.Pop_param (CG.Type.Addr); >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>> CG.If_true (handler, CG.Never); >>>>>> cvs diff: Diffing stmts >>>>>> Index: stmts/TryFinStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>> retrieving revision 1.6 >>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -299,6 +299,10 @@ >>>>>> CG.Load_nil (); >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> l := CG.Next_label (3); >>>>>> CG.Set_label (l, barrier := TRUE); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>> Index: stmts/TryStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>> retrieving revision 1.3 >>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -10,7 +10,7 @@ >>>>>> >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>> >>>>>> TYPE >>>>>> @@ -411,6 +411,10 @@ >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>> ***********************************************) >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> IF (p.hasElse) THEN >>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>> >>>>>> >>>>>> The set_label before one of the PushEFrames could be moved down a bit, >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>>>> >>>>>> Thanks, >>>>>> - Jay >>>>>> >>>>>> >>>>>> ---------------------------------------- >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>> >>>>>>>> >>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>> >>>>>>>> >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>>>> where in the function it is. >>>>>>>> >>>>>>>> >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>> >>>>>>>> >>>>>>>> It is more work through, granted, I can understand that. >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>>>> >>>>>>>> >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>> >>>>>>>> >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>> And it might pessimize codegen in other ways. >>>>>>>> >>>>>>>> >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>>>> >>>>>>>> >>>>>>>> - Jay >>>>>>>> >>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>>>> since they can be nested. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>>>> local "EF1" for each try. >>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>>>> it in each EF* block? >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>>>> to in the front end, I need to read it more. >>>>>>>>> >>>>>>>>> something like: >>>>>>>>> >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>>>> END END END END F1; >>>>>>>>> => >>>>>>>>> >>>>>>>>> void F1() >>>>>>>>> { >>>>>>>>> jmp_buf* jb = 0; >>>>>>>>> EF1 a,b,c; >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>>>> do stuff 1... >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>>>> do stuff 2... >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>>>> do stuff 3... >>>>>>>>> } >>>>>>>>> >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>>>> features....) >>>>>>>>> >>>>>>>>> >>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>> >>>>>>>>> >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>> additional progress, you only ever know the last place you were in a >>>>>>>>> function. >>>>>>>>> That doesn't seem adequate. >>>>>>>>> >>>>>>>>> >>>>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>>>> same place. >>>>>>>>> >>>>>>>>> >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>>>> across functions. >>>>>>>>> I think somehow that is related here. >>>>>>>>> >>>>>>>>> >>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>> >>>>>>>>> >>>>>>>>> EXCEPTION E1; >>>>>>>>> EXCEPTION E2; >>>>>>>>> EXCEPTION E3; >>>>>>>>> >>>>>>>>> >>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>> CONST Function = "F4 "; >>>>>>>>> BEGIN >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> RAISE E1; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E2; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E3; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> END; >>>>>>>>> END F4; >>>>>>>>> >>>>>>>>> >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> I am OK with what you have currently: >>>>>>>>> >>>>>>>>> At each TRY: >>>>>>>>> >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>> 3. Execute the try block. >>>>>>>>> >>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>> >>>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>>>> is as poor as it is, since a better but still >>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>> >>>>>>>>> >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>> >>>>>>>>> >>>>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>>>> live the regression on other targets? >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>> >>>>>>>>> >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>>>> >>>>>>>>> >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>> >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>>>> merges, than n calls to alloca? >>>>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>> >>>>>>>>> >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>>>> per function >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>>>> of how many calls it makes per function, >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>> >>>>>>>>> >>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>> I'll still do some comparisons to release. >>>>>>>>> >>>>>>>>> >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>> I'll do more testing. >>>>>>>>> >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>> >>>>>>>>> >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>>>> the preexisting inefficiency. >>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>> >>>>>>>>> And second, either way, it could be better. >>>>>>>>> >>>>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>>>> it calls setjmp once. >>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>> represents the line number. >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>>>> incremented, every time you >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>>>> value can be stored. >>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>> switches on the integer >>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>> >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>>>> it -- check for NIL. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>>>> actually fairly small to read. >>>>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>>>> for every try/lock. >>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>>>> is written so that it should work >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>>>> probably is a function call there. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>>>> >>>>>>>>> >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>>>> the problem is addressed there. >>>>>>>>> >>>>>>>>> >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>>>> setjmp. >>>>>>>>> >>>>>>>>> - Jay/phone >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>>>> has been done here without diving into the diff. >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> diff attached >>>>>>>>> >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>> From: jkrell at elego.de >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>> >>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>> >>>>>>>>>> Modified files: >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>> >>>>>>>>>> Log message: >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>> >>>>>>>>>> to allocate jmp_buf >>>>>>>>>> >>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>> types with alignment > 64 bits >>>>>>>>>> >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 05:08:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 04:08:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: I don't think so, but maybe. For i := 1 to 10 do try finally end will run that generated code 10 times but only the 1st is needed. In general? I not sure. Jay/phone > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:56:48 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > CG calls are all compile-time generation of code. > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > - Jay > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> In the code below there are no initializations. > >> > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >> > >>> > >>> ps: I think there other non-ideal initializations here. > >>> e.g. > >>> > >>> > >>> TryFinStmt.m3:Compile2 > >>> (* declare and initialize the info record *) > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > >>> CG.Type.Struct, 0, in_memory := TRUE, > >>> up_level := FALSE, f := CG.Never); > >>> CG.Load_procedure (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_handler); > >>> CG.Load_static_link (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_frame); > >>> > >>> > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > >>> Granted, this is non-stack-walker code. > >>> > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > >>> > >>> - Jay > >>> > >>> ---------------------------------------- > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>> > >>>> > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > >>>> > >>>> TryStmt.m3 and TryFinStmt.m3: > >>>> > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>> up_level := FALSE, f := CG.Never); > >>>> > >>>> I agree though, this might not be ideal. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> I don't understand what you mean by "initializes to NIL". > >>>>> How are you creating the frame variable? > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>>>> > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> Ok. > >>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>> > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>> > >>>>>> > >>>>>> Index: misc/Marker.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>> retrieving revision 1.7 > >>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -233,6 +233,7 @@ > >>>>>> > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>> VAR new: BOOLEAN; > >>>>>> + label := CG.Next_label (); > >>>>>> BEGIN > >>>>>> (* int setjmp(void* ); *) > >>>>>> IF (setjmp = NIL) THEN > >>>>>> @@ -263,18 +264,25 @@ > >>>>>> Target.Word.cg_type, 0); > >>>>>> END; > >>>>>> > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>> + > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>>>> + > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> + (* END *) > >>>>>> + CG.Set_label (label); > >>>>>> > >>>>>> (* setmp(frame.jmpbuf) *) > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>> CG.If_true (handler, CG.Never); > >>>>>> cvs diff: Diffing stmts > >>>>>> Index: stmts/TryFinStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>> retrieving revision 1.6 > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -299,6 +299,10 @@ > >>>>>> CG.Load_nil (); > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> l := CG.Next_label (3); > >>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>> Index: stmts/TryStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>> retrieving revision 1.3 > >>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -10,7 +10,7 @@ > >>>>>> > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>> > >>>>>> TYPE > >>>>>> @@ -411,6 +411,10 @@ > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>> ***********************************************) > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> IF (p.hasElse) THEN > >>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>> > >>>>>> > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>>>> > >>>>>> Thanks, > >>>>>> - Jay > >>>>>> > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>> > >>>>>>>> > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>> > >>>>>>>> > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>>>> where in the function it is. > >>>>>>>> > >>>>>>>> > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>> > >>>>>>>> > >>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>>>> > >>>>>>>> > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>> > >>>>>>>> > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>> > >>>>>>>> > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>>>> > >>>>>>>> > >>>>>>>> - Jay > >>>>>>>> > >>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>>>> since they can be nested. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>>>> local "EF1" for each try. > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>>>> it in each EF* block? > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>> > >>>>>>>>> something like: > >>>>>>>>> > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>>>> END END END END F1; > >>>>>>>>> => > >>>>>>>>> > >>>>>>>>> void F1() > >>>>>>>>> { > >>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>> EF1 a,b,c; > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>>>> do stuff 1... > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>>>> do stuff 2... > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>>>> do stuff 3... > >>>>>>>>> } > >>>>>>>>> > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>>>> features....) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>>>> function. > >>>>>>>>> That doesn't seem adequate. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>>>> same place. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>>>> across functions. > >>>>>>>>> I think somehow that is related here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> EXCEPTION E1; > >>>>>>>>> EXCEPTION E2; > >>>>>>>>> EXCEPTION E3; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>> CONST Function = "F4 "; > >>>>>>>>> BEGIN > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> RAISE E1; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E2; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E3; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> END; > >>>>>>>>> END F4; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> I am OK with what you have currently: > >>>>>>>>> > >>>>>>>>> At each TRY: > >>>>>>>>> > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>> 3. Execute the try block. > >>>>>>>>> > >>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>>>> live the regression on other targets? > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>> > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>>>> merges, than n calls to alloca? > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>>>> per function > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>>>> of how many calls it makes per function, > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>> I'll do more testing. > >>>>>>>>> > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>>>> the preexisting inefficiency. > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>> > >>>>>>>>> And second, either way, it could be better. > >>>>>>>>> > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>>>> it calls setjmp once. > >>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>> represents the line number. > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>>>> incremented, every time you > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>>>> value can be stored. > >>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>> switches on the integer > >>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>> > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>>>> it -- check for NIL. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>>>> actually fairly small to read. > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>>>> for every try/lock. > >>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>>>> is written so that it should work > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>>>> probably is a function call there. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>>>> the problem is addressed there. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>>>> setjmp. > >>>>>>>>> > >>>>>>>>> - Jay/phone > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>>>> has been done here without diving into the diff. > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> diff attached > >>>>>>>>> > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>> > >>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>> > >>>>>>>>>> Modified files: > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>> > >>>>>>>>>> Log message: > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>> > >>>>>>>>>> to allocate jmp_buf > >>>>>>>>>> > >>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>> > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 7 05:24:31 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 23:24:31 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Ah, yes, I see. You're right. The same proc is stored multiple times. We could indeed simply have a variable initialized once with the value of the proc. On Jan 6, 2011, at 11:08 PM, Jay K wrote: > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>>>>>>> are allocating on every TRY where previously the storage was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 7 06:38:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 05:38:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Now, for all I know it is loading from a variable and the variable can change. That's my uncertainty. There is other similar code that I'm even less certain of, specifically: MODULE TryStmt; PROCEDURE Compile1 (p: P): Stmt.Outcomes = ??? (* declare and initialize the info record *) ??? info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, ????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_nil (); ??? CG.Store_addr (info, M3RT.EA_exception); It could very well be that in: ?For i := 1 to 10 do try ... may or may not throw ... except else info needs to be nulled each time through. If you fixup this stuff, I'll know more easily how to remove the allocas from loops. Or maybe I can figure it out anyway from your clue. (Or maybe I'll first go after Mika's two failing pieces of code..) Thanks, ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 23:24:31 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I see. You're right. > The same proc is stored multiple times. > We could indeed simply have a variable initialized once with the value > of the proc. > > > On Jan 6, 2011, at 11:08 PM, Jay K wrote: > > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In > general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic > executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going > to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same > initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of > m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level > to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be > initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved > down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, > but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp > implementation to one that relies on unwind support, so I don't think > the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to > return to. > > >>>>>>>> There would also be a volatile local integer, that gets > altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that > integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a > highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is > reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or > one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the > volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current > Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many > platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. > the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables > merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there > is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per > TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code > allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, > and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code > -- the > > >>>>>>>>> existance of the ternary operator, and that it only > evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite > like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you > were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within > itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep > longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global > unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated > by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our > implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working > and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about > jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend > automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n > calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, > even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to > setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could > keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder > relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already > worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for > each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as > the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any > try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the > integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or > rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple > sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more > testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > But now you > > >>>>>>>>> are allocating on every TRY where previously the storage > was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. > The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more > instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. > And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: > the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a > jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf > aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated > via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more > targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> > CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't > know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety > slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least > with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Fri Jan 7 08:25:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 7 Jan 2011 02:25:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > Now, for all I know it is loading from a variable and the variable can change. > That's my uncertainty. > > > There is other similar code that I'm even less certain of, specifically: > > MODULE TryStmt; > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > (* declare and initialize the info record *) > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_nil (); > CG.Store_addr (info, M3RT.EA_exception); > > It could very well be that in: > > For i := 1 to 10 do try ... may or may not throw ... except else > > info needs to be nulled each time through. > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > Or maybe I can figure it out anyway from your clue. > (Or maybe I'll first go after Mika's two failing pieces of code..) > > Thanks, > - Jay > > > > > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 23:24:31 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I see. You're right. >> The same proc is stored multiple times. >> We could indeed simply have a variable initialized once with the value >> of the proc. >> >> >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: >> >> I don't think so, but maybe. >> >> For i := 1 to 10 do try finally end >> >> will run that generated code 10 times but only the 1st is needed. In >> general? I not sure. >> >> Jay/phone >> >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> You are confusing code emitted in the body of the loop with dynamic >> executions of that code. >>> CG calls are all compile-time generation of code. >>> >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: >>> >>>> >>>> If I have a try/finally or lock in a loop, those lines aren't going >> to guaranteeably store the same values each time? >>>> >>>> - Jay >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> In the code below there are no initializations. >>>>> >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >>>>> >>>>>> >>>>>> ps: I think there other non-ideal initializations here. >>>>>> e.g. >>>>>> >>>>>> >>>>>> TryFinStmt.m3:Compile2 >>>>>> (* declare and initialize the info record *) >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, >> Target.Address.align, >>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>> up_level := FALSE, f := CG.Never); >>>>>> CG.Load_procedure (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); >>>>>> CG.Load_static_link (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); >>>>>> >>>>>> >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same >> initializations. >>>>>> Granted, this is non-stack-walker code. >>>>>> >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of >> m3front still.. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ---------------------------------------- >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>>>>> >>>>>>> >>>>>>> The same way as before. I think this operates at too low a level >> to get any automatic initialization. >>>>>>> >>>>>>> TryStmt.m3 and TryFinStmt.m3: >>>>>>> >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, >> Target.Address.align, >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>>> up_level := FALSE, f := CG.Never); >>>>>>> >>>>>>> I agree though, this might not be ideal. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ---------------------------------------- >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>> From: hosking at cs.purdue.edu >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>>>>> CC: m3commit at elegosoft.com >>>>>>>> To: jay.krell at cornell.edu >>>>>>>> >>>>>>>> I don't understand what you mean by "initializes to NIL". >>>>>>>> How are you creating the frame variable? >>>>>>>> If you do it properly the language semantics will cause it be >> initialized to NIL automatically. >>>>>>>> >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> Ok. >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>>>>> >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* >> to correct, >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>>>>> >>>>>>>>> >>>>>>>>> Index: misc/Marker.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>>>>> retrieving revision 1.7 >>>>>>>>> diff -u -w -r1.7 Marker.m3 >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -233,6 +233,7 @@ >>>>>>>>> >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>>>>> VAR new: BOOLEAN; >>>>>>>>> + label := CG.Next_label (); >>>>>>>>> BEGIN >>>>>>>>> (* int setjmp(void* ); *) >>>>>>>>> IF (setjmp = NIL) THEN >>>>>>>>> @@ -263,18 +264,25 @@ >>>>>>>>> Target.Word.cg_type, 0); >>>>>>>>> END; >>>>>>>>> >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>>>>> + >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, >> CG.Maybe); >>>>>>>>> + >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> + (* END *) >>>>>>>>> + CG.Set_label (label); >>>>>>>>> >>>>>>>>> (* setmp(frame.jmpbuf) *) >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> CG.Pop_param (CG.Type.Addr); >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>>>>> CG.If_true (handler, CG.Never); >>>>>>>>> cvs diff: Diffing stmts >>>>>>>>> Index: stmts/TryFinStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>>>>> retrieving revision 1.6 >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -299,6 +299,10 @@ >>>>>>>>> CG.Load_nil (); >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> l := CG.Next_label (3); >>>>>>>>> CG.Set_label (l, barrier := TRUE); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>>>>> Index: stmts/TryStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>>>>> retrieving revision 1.3 >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -10,7 +10,7 @@ >>>>>>>>> >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, >> Error, Marker; >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>>>>> >>>>>>>>> TYPE >>>>>>>>> @@ -411,6 +411,10 @@ >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>>>>> ***********************************************) >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> IF (p.hasElse) THEN >>>>>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>>>>> >>>>>>>>> >>>>>>>>> The set_label before one of the PushEFrames could be moved >> down a bit, >>>>>>>>> to after the NIL initialization, and that'd fix some cases, >> but I think not all. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ---------------------------------------- >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>> >>>>>>>>>> At this point, we are trying to move away from the setjmp >> implementation to one that relies on unwind support, so I don't think >> the effort here is worthwhile. >>>>>>>>>> >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to >> return to. >>>>>>>>>>> There would also be a volatile local integer, that gets >> altered at certain points through the function. >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that >> integer to determine where to "really" go. >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a >> highly optimized frame based exception >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is >> reserved to be the head of the linked list of frames. >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> So the result is that a function with one or more tries, or >> one or more locals with destructors, >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the >> volatile local integer to indicate >>>>>>>>>>> where in the function it is. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> If NT/x86 were inefficient more analogous to current >> Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> It is more work through, granted, I can understand that. >>>>>>>>>>> And given that we have a much better option for many >> platforms, the payoff would be reduced. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. >> the previous approach. >>>>>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>>>>> And it might pessimize codegen in other ways. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables >> merely describe, again, which >>>>>>>>>>> function/frame to return to, and that within the frame there >> is a local integer to determine >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a >> switch. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> - Jay >>>>>>>>>>> >>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per >> TRY scope, >>>>>>>>>>>> since they can be nested. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code >> allocates a >>>>>>>>>>>> local "EF1" for each try. >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, >> and store >>>>>>>>>>>> it in each EF* block? >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily >> figure out how >>>>>>>>>>>> to in the front end, I need to read it more. >>>>>>>>>>>> >>>>>>>>>>>> something like: >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 >> do stuff 3 >>>>>>>>>>>> END END END END F1; >>>>>>>>>>>> => >>>>>>>>>>>> >>>>>>>>>>>> void F1() >>>>>>>>>>>> { >>>>>>>>>>>> jmp_buf* jb = 0; >>>>>>>>>>>> EF1 a,b,c; >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY1 >>>>>>>>>>>> do stuff 1... >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY2 >>>>>>>>>>>> do stuff 2... >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY3 >>>>>>>>>>>> do stuff 3... >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code >> -- the >>>>>>>>>>>> existance of the ternary operator, and that it only >> evaluates one side >>>>>>>>>>>> or the other, and that assignment is expression..I quite >> like those >>>>>>>>>>>> features....) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>>>>> additional progress, you only ever know the last place you >> were in a >>>>>>>>>>>> function. >>>>>>>>>>>> That doesn't seem adequate. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> What if a function raises an exception, catches it within >> itself, and >>>>>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>>>>> It won't know where to resume, right? It's just keep >> longjmping to the >>>>>>>>>>>> same place. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and >> "global unwind". >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global >> unwind" is >>>>>>>>>>>> across functions. >>>>>>>>>>>> I think somehow that is related here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> EXCEPTION E1; >>>>>>>>>>>> EXCEPTION E2; >>>>>>>>>>>> EXCEPTION E3; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>>>>> CONST Function = "F4 "; >>>>>>>>>>>> BEGIN >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> RAISE E1; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E2; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E3; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> END; >>>>>>>>>>>> END F4; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> I am OK with what you have currently: >>>>>>>>>>>> >>>>>>>>>>>> At each TRY: >>>>>>>>>>>> >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated >> by checking >>>>>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>>>>> 3. Execute the try block. >>>>>>>>>>>> >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in >> functions that use try. >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n >> calls for n trys. >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our >> implementation >>>>>>>>>>>> is as poor as it is, since a better but still >>>>>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Or just give me a week or few to get stack walking working >> and then >>>>>>>>>>>> live the regression on other targets? >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* >> certainly >>>>>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> It *is* nice to not have have the frontend know about >> jmpbuf size. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be >> used so easily. >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>>>>> >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I >> guess your >>>>>>>>>>>> point is, you'd rather have n locals, which the backend >> automatically >>>>>>>>>>>> merges, than n calls to alloca? >>>>>>>>>>>> It's not a huge difference -- there are still going to be n >> calls to >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, >> even if >>>>>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - It could make a maximum of one call to >> setjmp/pthread_getspecific >>>>>>>>>>>> per function >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could >> keep track >>>>>>>>>>>> of how many calls it makes per function, >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>>>>> I'll still do some comparisons to release. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I'll still be looking into using the gcc unwinder >> relatively soon. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already >> worked maybe? >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>>>>> I'll do more testing. >>>>>>>>>>>> >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for >> each TRY >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So the additional inefficiency is multiplied the same as >> the rest of >>>>>>>>>>>> the preexisting inefficiency. >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>>>>> >>>>>>>>>>>> And second, either way, it could be better. >>>>>>>>>>>> >>>>>>>>>>>> Basically, the model should be, that if a function has any >> try or lock, >>>>>>>>>>>> it calls setjmp once. >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>>>>> represents the line number. >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the >> integer is >>>>>>>>>>>> incremented, every time you >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or >> rather, the >>>>>>>>>>>> value can be stored. >>>>>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>>>>> switches on the integer >>>>>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>>>>> >>>>>>>>>>>> This is how other compilers work and it is a fairly simple >> sensible approach. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more >> testing and fix >>>>>>>>>>>> it -- check for NIL. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. >> But now you >>>>>>>>>>>> are allocating on every TRY where previously the storage >> was statically >>>>>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> I've back with full keyboard if more explanation needed. >> The diff is >>>>>>>>>>>> actually fairly small to read. >>>>>>>>>>>> I understand it is definitely less efficient, a few more >> instructions >>>>>>>>>>>> for every try/lock. >>>>>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- >> the change >>>>>>>>>>>> is written so that it should work >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. >> And there >>>>>>>>>>>> probably is a function call there. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: >> the jumpbuf in >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a >> jumpbuf. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf >> aligned to >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and >> alloca seems >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine >> currently to see if >>>>>>>>>>>> the problem is addressed there. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated >> via a stack >>>>>>>>>>>> walker. I wanted to do this first though, while more >> targets using >>>>>>>>>>>> setjmp. >>>>>>>>>>>> >>>>>>>>>>>> - Jay/phone >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>>>>> >> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't >> know what >>>>>>>>>>>> has been done here without diving into the diff. >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> diff attached >>>>>>>>>>>> >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>>>>> From: jkrell at elego.de >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>>>>> >>>>>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>>>>> >>>>>>>>>>>>> Modified files: >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>>>>> >>>>>>>>>>>>> Log message: >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>>>>> >>>>>>>>>>>>> to allocate jmp_buf >>>>>>>>>>>>> >>>>>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>>>>> types with alignment > 64 bits >>>>>>>>>>>>> >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety >> slow path. >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least >> with gcc backend. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 11:46:05 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 10:46:05 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> , Message-ID: > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. Correct. That part is easy to code and I have correct on my machine. What I don't have is doing the initialization, early enough in the generated code to be just once. ?> Perhaps that is not so easy, because you need to declare the variable in the outermost scope. Right. And still one per try. The current code is pretty bad, for try within a loop. I should also point out that the alloca approach is using a fair amount more stack. ?- the alloca is rounded up a lot for alignment ?- the extra pointer; but mainly I think the alignment Agreed, what I want to fix is more significant than the other "problem" I brought up, since one is allocating more and more stack, the other is not. One "problem" I just introduced, hasn't been around any amount of time, the other is long standing and nobody noticed. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Fri, 7 Jan 2011 02:25:30 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? > > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. > My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. > > On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > > > > Now, for all I know it is loading from a variable and the variable can change. > > That's my uncertainty. > > > > > > There is other similar code that I'm even less certain of, specifically: > > > > MODULE TryStmt; > > > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > > > (* declare and initialize the info record *) > > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_nil (); > > CG.Store_addr (info, M3RT.EA_exception); > > > > It could very well be that in: > > > > For i := 1 to 10 do try ... may or may not throw ... except else > > > > info needs to be nulled each time through. > > > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > > Or maybe I can figure it out anyway from your clue. > > (Or maybe I'll first go after Mika's two failing pieces of code..) > > > > Thanks, > > - Jay > > > > > > > > > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 23:24:31 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I see. You're right. > >> The same proc is stored multiple times. > >> We could indeed simply have a variable initialized once with the value > >> of the proc. > >> > >> > >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: > >> > >> I don't think so, but maybe. > >> > >> For i := 1 to 10 do try finally end > >> > >> will run that generated code 10 times but only the 1st is needed. In > >> general? I not sure. > >> > >> Jay/phone > >> > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> You are confusing code emitted in the body of the loop with dynamic > >> executions of that code. > >>> CG calls are all compile-time generation of code. > >>> > >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: > >>> > >>>> > >>>> If I have a try/finally or lock in a loop, those lines aren't going > >> to guaranteeably store the same values each time? > >>>> > >>>> - Jay > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> In the code below there are no initializations. > >>>>> > >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> ps: I think there other non-ideal initializations here. > >>>>>> e.g. > >>>>>> > >>>>>> > >>>>>> TryFinStmt.m3:Compile2 > >>>>>> (* declare and initialize the info record *) > >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > >> Target.Address.align, > >>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>> up_level := FALSE, f := CG.Never); > >>>>>> CG.Load_procedure (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); > >>>>>> CG.Load_static_link (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); > >>>>>> > >>>>>> > >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same > >> initializations. > >>>>>> Granted, this is non-stack-walker code. > >>>>>> > >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of > >> m3front still.. > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>>>>> > >>>>>>> > >>>>>>> The same way as before. I think this operates at too low a level > >> to get any automatic initialization. > >>>>>>> > >>>>>>> TryStmt.m3 and TryFinStmt.m3: > >>>>>>> > >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > >> Target.Address.align, > >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>>> up_level := FALSE, f := CG.Never); > >>>>>>> > >>>>>>> I agree though, this might not be ideal. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ---------------------------------------- > >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>> To: jay.krell at cornell.edu > >>>>>>>> > >>>>>>>> I don't understand what you mean by "initializes to NIL". > >>>>>>>> How are you creating the frame variable? > >>>>>>>> If you do it properly the language semantics will cause it be > >> initialized to NIL automatically. > >>>>>>>> > >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>>>>> > >>>>>>>>> > >>>>>>>>> Ok. > >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>>>>> > >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > >> to correct, > >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Index: misc/Marker.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>>>>> retrieving revision 1.7 > >>>>>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -233,6 +233,7 @@ > >>>>>>>>> > >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>>>>> VAR new: BOOLEAN; > >>>>>>>>> + label := CG.Next_label (); > >>>>>>>>> BEGIN > >>>>>>>>> (* int setjmp(void* ); *) > >>>>>>>>> IF (setjmp = NIL) THEN > >>>>>>>>> @@ -263,18 +264,25 @@ > >>>>>>>>> Target.Word.cg_type, 0); > >>>>>>>>> END; > >>>>>>>>> > >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>>>>> + > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > >> CG.Maybe); > >>>>>>>>> + > >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> + (* END *) > >>>>>>>>> + CG.Set_label (label); > >>>>>>>>> > >>>>>>>>> (* setmp(frame.jmpbuf) *) > >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>>>>> CG.If_true (handler, CG.Never); > >>>>>>>>> cvs diff: Diffing stmts > >>>>>>>>> Index: stmts/TryFinStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>>>>> retrieving revision 1.6 > >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -299,6 +299,10 @@ > >>>>>>>>> CG.Load_nil (); > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> l := CG.Next_label (3); > >>>>>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>>>>> Index: stmts/TryStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>>>>> retrieving revision 1.3 > >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -10,7 +10,7 @@ > >>>>>>>>> > >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > >> Error, Marker; > >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>>>>> > >>>>>>>>> TYPE > >>>>>>>>> @@ -411,6 +411,10 @@ > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>>>>> ***********************************************) > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> IF (p.hasElse) THEN > >>>>>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The set_label before one of the PushEFrames could be moved > >> down a bit, > >>>>>>>>> to after the NIL initialization, and that'd fix some cases, > >> but I think not all. > >>>>>>>>> > >>>>>>>>> Thanks, > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ---------------------------------------- > >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>> > >>>>>>>>>> At this point, we are trying to move away from the setjmp > >> implementation to one that relies on unwind support, so I don't think > >> the effort here is worthwhile. > >>>>>>>>>> > >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to > >> return to. > >>>>>>>>>>> There would also be a volatile local integer, that gets > >> altered at certain points through the function. > >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that > >> integer to determine where to "really" go. > >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a > >> highly optimized frame based exception > >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is > >> reserved to be the head of the linked list of frames. > >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> So the result is that a function with one or more tries, or > >> one or more locals with destructors, > >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the > >> volatile local integer to indicate > >>>>>>>>>>> where in the function it is. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> If NT/x86 were inefficient more analogous to current > >> Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>>>>> And given that we have a much better option for many > >> platforms, the payoff would be reduced. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. > >> the previous approach. > >>>>>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables > >> merely describe, again, which > >>>>>>>>>>> function/frame to return to, and that within the frame there > >> is a local integer to determine > >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > >> switch. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> - Jay > >>>>>>>>>>> > >>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per > >> TRY scope, > >>>>>>>>>>>> since they can be nested. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code > >> allocates a > >>>>>>>>>>>> local "EF1" for each try. > >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, > >> and store > >>>>>>>>>>>> it in each EF* block? > >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > >> figure out how > >>>>>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>>>>> > >>>>>>>>>>>> something like: > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > >> do stuff 3 > >>>>>>>>>>>> END END END END F1; > >>>>>>>>>>>> => > >>>>>>>>>>>> > >>>>>>>>>>>> void F1() > >>>>>>>>>>>> { > >>>>>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>>>>> EF1 a,b,c; > >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY1 > >>>>>>>>>>>> do stuff 1... > >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY2 > >>>>>>>>>>>> do stuff 2... > >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY3 > >>>>>>>>>>>> do stuff 3... > >>>>>>>>>>>> } > >>>>>>>>>>>> > >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code > >> -- the > >>>>>>>>>>>> existance of the ternary operator, and that it only > >> evaluates one side > >>>>>>>>>>>> or the other, and that assignment is expression..I quite > >> like those > >>>>>>>>>>>> features....) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>>>>> additional progress, you only ever know the last place you > >> were in a > >>>>>>>>>>>> function. > >>>>>>>>>>>> That doesn't seem adequate. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> What if a function raises an exception, catches it within > >> itself, and > >>>>>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>>>>> It won't know where to resume, right? It's just keep > >> longjmping to the > >>>>>>>>>>>> same place. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > >> "global unwind". > >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global > >> unwind" is > >>>>>>>>>>>> across functions. > >>>>>>>>>>>> I think somehow that is related here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> EXCEPTION E1; > >>>>>>>>>>>> EXCEPTION E2; > >>>>>>>>>>>> EXCEPTION E3; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>>>>> CONST Function = "F4 "; > >>>>>>>>>>>> BEGIN > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> RAISE E1; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E2; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E3; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> END; > >>>>>>>>>>>> END F4; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> I am OK with what you have currently: > >>>>>>>>>>>> > >>>>>>>>>>>> At each TRY: > >>>>>>>>>>>> > >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated > >> by checking > >>>>>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>>>>> 3. Execute the try block. > >>>>>>>>>>>> > >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > >> functions that use try. > >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > >> calls for n trys. > >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our > >> implementation > >>>>>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Or just give me a week or few to get stack walking working > >> and then > >>>>>>>>>>>> live the regression on other targets? > >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > >> certainly > >>>>>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> It *is* nice to not have have the frontend know about > >> jmpbuf size. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > >> used so easily. > >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>>>>> > >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > >> guess your > >>>>>>>>>>>> point is, you'd rather have n locals, which the backend > >> automatically > >>>>>>>>>>>> merges, than n calls to alloca? > >>>>>>>>>>>> It's not a huge difference -- there are still going to be n > >> calls to > >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, > >> even if > >>>>>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - It could make a maximum of one call to > >> setjmp/pthread_getspecific > >>>>>>>>>>>> per function > >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could > >> keep track > >>>>>>>>>>>> of how many calls it makes per function, > >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I'll still be looking into using the gcc unwinder > >> relatively soon. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already > >> worked maybe? > >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>>>>> I'll do more testing. > >>>>>>>>>>>> > >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for > >> each TRY > >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So the additional inefficiency is multiplied the same as > >> the rest of > >>>>>>>>>>>> the preexisting inefficiency. > >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>>>>> > >>>>>>>>>>>> And second, either way, it could be better. > >>>>>>>>>>>> > >>>>>>>>>>>> Basically, the model should be, that if a function has any > >> try or lock, > >>>>>>>>>>>> it calls setjmp once. > >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>>>>> represents the line number. > >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the > >> integer is > >>>>>>>>>>>> incremented, every time you > >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or > >> rather, the > >>>>>>>>>>>> value can be stored. > >>>>>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>>>>> switches on the integer > >>>>>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>>>>> > >>>>>>>>>>>> This is how other compilers work and it is a fairly simple > >> sensible approach. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more > >> testing and fix > >>>>>>>>>>>> it -- check for NIL. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > >> But now you > >>>>>>>>>>>> are allocating on every TRY where previously the storage > >> was statically > >>>>>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> I've back with full keyboard if more explanation needed. > >> The diff is > >>>>>>>>>>>> actually fairly small to read. > >>>>>>>>>>>> I understand it is definitely less efficient, a few more > >> instructions > >>>>>>>>>>>> for every try/lock. > >>>>>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > >> the change > >>>>>>>>>>>> is written so that it should work > >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. > >> And there > >>>>>>>>>>>> probably is a function call there. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> > >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: > >> the jumpbuf in > >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a > >> jumpbuf. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf > >> aligned to > >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > >> alloca seems > >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > >> currently to see if > >>>>>>>>>>>> the problem is addressed there. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated > >> via a stack > >>>>>>>>>>>> walker. I wanted to do this first though, while more > >> targets using > >>>>>>>>>>>> setjmp. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay/phone > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>>>>> > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't > >> know what > >>>>>>>>>>>> has been done here without diving into the diff. > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> diff attached > >>>>>>>>>>>> > >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Modified files: > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Log message: > >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>>>>> > >>>>>>>>>>>>> to allocate jmp_buf > >>>>>>>>>>>>> > >>>>>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>>>>> > >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety > >> slow path. > >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least > >> with gcc backend. From jkrell at elego.de Fri Jan 7 21:26:44 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:26:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202644.D50812474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:26:44 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Fri Jan 7 21:29:00 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:29:00 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202900.167F32474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:29:00 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Sat Jan 8 05:57:15 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 5:57:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108045715.A9F19CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 05:57:15 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: comments only: "won" => "won the race"; "!" => "." From jkrell at elego.de Sat Jan 8 06:01:20 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:01:20 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108050121.3B57FCC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:01:20 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: leave initMu before calling RegisterFinalCleanup, to avoid deadlock with AtForkPrepare From jay.krell at cornell.edu Sat Jan 8 06:05:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 05:05:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.245 diff -u -r1.245 ThreadPThread.m3 --- ThreadPThread.m3??? 8 Jan 2011 04:57:15 -0000??? 1.245 +++ ThreadPThread.m3??? 8 Jan 2011 04:58:57 -0000 @@ -96,6 +96,7 @@ ?PROCEDURE InitMutex (VAR m: pthread_mutex_t; root: REFANY; ????????????????????? Clean: PROCEDURE(root: REFANY)) = ?? VAR mutex := pthread_mutex_new(); +????? register := FALSE; ?? BEGIN ???? TRY ?????? WITH r = pthread_mutex_lock(initMu) DO <*ASSERT r=0*> END; @@ -103,13 +104,24 @@ ?????? IF m # NIL THEN RETURN END; ?????? (* We won the race, but we might have failed to allocate. *) ?????? IF mutex = NIL THEN RTE.Raise (RTE.T.OutOfMemory) END; -????? RTHeapRep.RegisterFinalCleanup (root, Clean); ?????? m := mutex; ?????? mutex := NIL; +????? register := TRUE; ???? FINALLY ?????? WITH r = pthread_mutex_unlock(initMu) DO <*ASSERT r=0*> END; ?????? pthread_mutex_delete(mutex); ???? END; +??? IF register THEN +????? (* RegisterFinalCleanup serializes itself using RTOS.LockHeap. +???????? Call it outside initMu to avoid deadlock with AtForkPrepare. +???????? Register can happen outside a lock because the root is yet +???????? alive and therefore will not be collected between pthread_mutex_new +???????? and RegisterFinalCleanup. We are careful to only RegisterFinalCleanup +???????? once -- not in the lost race cases -- though it does not clearly +???????? matter. +?????? *) +????? RTHeapRep.RegisterFinalCleanup (root, Clean); +??? END; ?? END InitMutex; ? ?PROCEDURE LockMutex (m: Mutex) = I wonder if we should dispense with initMu and eagerly initialize all mutexes. ?- Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 06:01:20 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare > From jkrell at elego.de Sat Jan 8 06:22:51 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:22:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108052251.34065CC365@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:22:51 Modified files: cm3/m3-sys/cminstall/src/config-no-install/: I386.common Log message: -march=i586 => -march=i686 to fix test case p249: ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [65]) (const_int 0 [0x0])) (set (reg:SI 5 di [63]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg:SI 5 di [63]))) (set (reg/f:SI 4 si [64]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg/f:SI 16 argp))) (set (mem/s/c:BLK (reg:SI 5 di [63]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg/f:SI 16 argp) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [65])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [65]) (expr_list:REG_UNUSED (reg/f:SI 4 si [64]) (expr_list:REG_UNUSED (reg:SI 5 di [63]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 probably merits further investigation From jkrell at elego.de Sat Jan 8 09:15:22 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:15:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108081522.7A4C12474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:15:21 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: more LONGINT subrange problems, this now has 3 internal codegen errors, due to stack type and expected type mismatches From jkrell at elego.de Sat Jan 8 09:37:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:37:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083705.7F8E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:37:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: make errors visible on stdout or stderr, much better now we get: jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) 4 errors encountered (this should probably say 3) compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Sat Jan 8 09:39:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083905.9D49E2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: put back 'self' as 'u' in PutErr, for smaller historical diff From jkrell at elego.de Sat Jan 8 09:39:34 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083934.F0E71CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:34 Modified files: cm3/m3-sys/m3middle/src/: M3RT.m3 Log message: remove unused RoundUp function From jay.krell at cornell.edu Sat Jan 8 09:38:09 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 08:38:09 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108083705.7F8E22474003@birch.elegosoft.com> References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: Index: src/M3CG_Check.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v retrieving revision 1.13 diff -u -r1.13 M3CG_Check.m3 --- src/M3CG_Check.m3??? 1 Nov 2010 09:37:23 -0000??? 1.13 +++ src/M3CG_Check.m3??? 8 Jan 2011 08:36:01 -0000 @@ -57,6 +57,7 @@ ???????? s_push (t: Type) := Stack_Push; ???????? s_repush () := Stack_Repush; ???????? s_empty () := Stack_Empty; +??????? PutErr (a, b, c: TEXT) := PutErr; ?????? OVERRIDES ???????? set_error_handler := set_error_handler; ???????? begin_unit := begin_unit; @@ -185,10 +186,11 @@ ? ?(*--------------------------------------------------------- low level I/O ---*) ? -PROCEDURE PutErr (u: U;? a, b, c: TEXT := NIL) = +PROCEDURE PutErr (self: U;? a, b, c: TEXT := NIL) = ?? BEGIN -??? u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); -??? INC (u.n_errors); +??? self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); +??? self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); +??? INC (self.n_errors); ?? END PutErr; ? ?(*-------------------------------------------------------- stack checking ---*) Hm. I think I could have left "self" named "u". I'll try that... ? - Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 09:37:05 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 09:37:05 > > Modified files: > cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > > Log message: > make errors visible on stdout or stderr, much better > now we get: > jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > --- building in I386_DARWIN --- > > new source -> compiling Main.m3 > "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > 4 errors encountered (this should probably say 3) > compilation failed => not building program "pgm" > Fatal Error: package build failed > From jkrell at elego.de Sun Jan 9 01:10:55 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:10:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001055.9F43A2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:10:55 Modified files: cm3/m3-db/postgres95/src/: m3makefile Log message: only call configure_system_libs if it is defined; config files out of date? From jkrell at elego.de Sun Jan 9 01:11:32 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:11:32 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001133.4EC5F2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:11:32 Modified files: cm3/scripts/python/: upgrade.py Log message: CopyConfigForDevelopment => CopyConfigForDistribution From hosking at cs.purdue.edu Sun Jan 9 01:17:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:17:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare From jay.krell at cornell.edu Sun Jan 9 01:32:11 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 00:32:11 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108050121.3B57FCC37A@birch.elegosoft.com>, Message-ID: Oops, good catch on the leak, and I'll try that now. ?- Jay ---------------------------------------- > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:17:30 -0500 > To: jkrell at elego.de > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. > > Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). > > On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/08 06:01:20 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > > with AtForkPrepare > From jkrell at elego.de Sun Jan 9 01:36:10 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:36:10 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109003611.5C4C2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:36:10 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: go back a versoin, to 1.245 From jkrell at elego.de Sun Jan 9 01:45:31 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:45:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109004531.4CCC3CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:45:31 Modified files: cm3/scripts/python/: upgrade.py Log message: oops From hosking at cs.purdue.edu Sun Jan 9 01:51:58 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:51:58 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From hosking at cs.purdue.edu Sun Jan 9 01:27:44 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:27:44 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <7EC18C1D-B1F2-4948-8369-15591226DCD6@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From jay.krell at cornell.edu Sun Jan 9 02:15:38 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 01:15:38 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> References: <20110108083705.7F8E22474003@birch.elegosoft.com> , <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> Message-ID: Right. I made it "self" to follow the style of "member functions" ("methods", whatever) and then back to "u" for historical stability. Arguably either way. Not a big deal though. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:51:58 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > It always used to be u, not self. > > On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > > > > Index: src/M3CG_Check.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > > retrieving revision 1.13 > > diff -u -r1.13 M3CG_Check.m3 > > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > > @@ -57,6 +57,7 @@ > > s_push (t: Type) := Stack_Push; > > s_repush () := Stack_Repush; > > s_empty () := Stack_Empty; > > + PutErr (a, b, c: TEXT) := PutErr; > > OVERRIDES > > set_error_handler := set_error_handler; > > begin_unit := begin_unit; > > @@ -185,10 +186,11 @@ > > > > (*--------------------------------------------------------- low level I/O ---*) > > > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > > BEGIN > > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > - INC (u.n_errors); > > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > + INC (self.n_errors); > > END PutErr; > > > > (*-------------------------------------------------------- stack checking ---*) > > > > Hm. I think I could have left "self" named "u". I'll try that... > > > > - Jay > > > > > > ---------------------------------------- > >> Date: Sat, 8 Jan 2011 09:37:05 +0000 > >> To: m3commit at elegosoft.com > >> From: jkrell at elego.de > >> Subject: [M3commit] CVS Update: cm3 > >> > >> CVSROOT: /usr/cvs > >> Changes by: jkrell at birch. 11/01/08 09:37:05 > >> > >> Modified files: > >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > >> > >> Log message: > >> make errors visible on stdout or stderr, much better > >> now we get: > >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > >> --- building in I386_DARWIN --- > >> > >> new source -> compiling Main.m3 > >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > >> 4 errors encountered (this should probably say 3) > >> compilation failed => not building program "pgm" > >> Fatal Error: package build failed > >> > > > From jkrell at elego.de Sun Jan 9 03:36:46 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 3:36:46 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109023648.2344ACC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 03:36:46 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap later in ForkPrepare, try to fix deadlock with mutex initialization From hosking at elego.de Sun Jan 9 12:01:49 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:01:49 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110149.DD5C52474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:01:49 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: While holding initMu InitMutex invokes RegisterFinalCleanup which acquires heapMu. Make sure that AtForkPrepare and AtForkParent both acquire/release these mutexes in the same order. From hosking at elego.de Sun Jan 9 12:07:13 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:07:13 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110713.A4384CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:07:13 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors from conflicts. From hosking at elego.de Sun Jan 9 20:56:31 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 20:56:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109195631.58C2FCC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 20:56:31 Modified files: cm3/m3-libs/arithmetic/doc/: backgnd.html Log message: Weird typo: the prefix "stat" was at some point replaced with "statistic", erroneously. From jkrell at elego.de Mon Jan 10 09:03:50 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 10 Jan 2011 9:03:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110110080350.4F9092474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/10 09:03:50 Modified files: cm3/m3-libs/arithmetic/doc/: wpress.txt Log message: "statistic" => "stat" From hosking at elego.de Tue Jan 11 05:56:50 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 5:56:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111045650.61C57247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 05:56:50 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Candidate fix for AtForkPrepare deadlock with InitMutex. From hosking at elego.de Tue Jan 11 06:14:01 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 6:14:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111051402.A39C2247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 06:14:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: initMu before heapMu to avoid potential deadlock between AtForkPrepare and InitMutex. From jkrell at elego.de Tue Jan 11 09:02:05 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 11 Jan 2011 9:02:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111080205.9D8F1CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/11 09:02:05 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: whitespace only: right justify line continuation backslashes This is harder to maintain (write/type) but easier to read. From mika at elego.de Tue Jan 11 16:57:22 2011 From: mika at elego.de (Mika Nystrom) Date: Tue, 11 Jan 2011 16:57:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111155722.830B7CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/11 16:57:22 Added files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 m3makefile m3overrides Log message: thread testing program. compile and run, expect to see output as follows: Writing file...done Creating reader threads...done Creating forker threads...done Creating allocator threads...done running... laziest thread is 1294760062 seconds behind laziest thread is 11 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 8 seconds behind laziest thread is 10 seconds behind laziest thread is 7 seconds behind laziest thread is 8 seconds behind program stops on its own. From hosking at elego.de Wed Jan 12 01:37:59 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 1:37:59 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112003759.AE706CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 01:37:59 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Oops, so-called "fix" last night was completely broken (tired!). [Mika, please try this latest] From jay.krell at cornell.edu Wed Jan 12 02:58:57 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 01:58:57 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110112003759.AE706CC37A@birch.elegosoft.com> References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense with most of the code implementing it, right? ie: no inCritical, no holder, no condition variables? - Jay ---------------------------------------- > Date: Wed, 12 Jan 2011 01:37:59 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/12 01:37:59 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > Oops, so-called "fix" last night was completely broken (tired!). > [Mika, please try this latest] > From jay.krell at cornell.edu Wed Jan 12 03:00:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 02:00:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com>, Message-ID: er, not quite, I forgot there is BroadcastHeap... - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at elego.de; m3commit at elegosoft.com > Date: Wed, 12 Jan 2011 01:58:57 +0000 > Subject: Re: [M3commit] CVS Update: cm3 > > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- > > Date: Wed, 12 Jan 2011 01:37:59 +0000 > > To: m3commit at elegosoft.com > > From: hosking at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: hosking at birch. 11/01/12 01:37:59 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > Oops, so-called "fix" last night was completely broken (tired!). > > [Mika, please try this latest] > > From jkrell at elego.de Wed Jan 12 08:00:34 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 12 Jan 2011 8:00:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112070034.7D36CCC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/12 08:00:34 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: align Jumpbuf_size, which appears needed for Win32 From hosking at cs.purdue.edu Wed Jan 12 18:15:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 12:15:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: <0722C93E-A3B8-493C-A15E-A32ED378F815@cs.purdue.edu> No, not really. Recursive mutexes are not supported on all platforms. Also, in the reql world we will avoid using mutexes in most instances, instead using lock reservation, etc. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 11, 2011, at 8:58 PM, Jay K wrote: > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- >> Date: Wed, 12 Jan 2011 01:37:59 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/12 01:37:59 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 >> >> Log message: >> Oops, so-called "fix" last night was completely broken (tired!). >> [Mika, please try this latest] >> From hosking at elego.de Wed Jan 12 19:16:34 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:16:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181634.89BC2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:16:34 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Can we rely on pthread_mutex_t always being a reference? Perhaps not, so don't use the locks array. From hosking at elego.de Wed Jan 12 19:18:08 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:18:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181808.52D04CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:18:08 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThreadC.c Log message: Eliminate initMu and lock heap instead, to avoid deadlock between InitMutex and AtForkPrepare. From hosking at elego.de Wed Jan 12 19:33:16 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:33:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112183316.3F661CC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:33:16 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors. From hosking at elego.de Thu Jan 13 02:37:40 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 2:37:40 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113013740.B85192474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 02:37:40 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for InitMutex instead of initMu to avoid deadlock between Initmutex and AtForkParent. From jay.krell at cornell.edu Thu Jan 13 02:53:06 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 01:53:06 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113013740.B85192474003@birch.elegosoft.com> References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: I haven't lookd, but it sounds like the idea is, use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? ie. resolve problems in a graph by merging nodes. I was also wondering if, maybe, we can initialize mutexex/condition variables eagerly instead of on-demand? Therefore without locking? I know that currently there's no interface from the generated code to the runtime for that. It's a tradeoff. Presumably/hopefully there are many mutexes and condition variables that are never used, and initializing them would just be a slow down. - Jay ---------------------------------------- > Date: Thu, 13 Jan 2011 02:37:40 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/13 02:37:40 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 > ThreadPThread.m3 > ThreadPThreadC.c > > Log message: > Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for > InitMutex instead of initMu to avoid deadlock between Initmutex and > AtForkParent. > From hosking at cs.purdue.edu Thu Jan 13 03:59:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 21:59:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: <7F42A0FD-D6EC-49BA-889B-3F15158173DD@cs.purdue.edu> On Jan 12, 2011, at 8:53 PM, Jay K wrote: > > I haven't lookd, but it sounds like the idea is, > use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? > ie. resolve problems in a graph by merging nodes. Yes. > I was also wondering if, maybe, we can initialize > mutexex/condition variables eagerly instead of on-demand? > Therefore without locking? Seems overkill for types that inherit from MUTEX but are never used for locking. Also, ultimately a Modula-3 MUTEX won't be one-to-one with pthread mutexes. > I know that currently there's no interface from the > generated code to the runtime for that. > > > It's a tradeoff. Presumably/hopefully there are many > mutexes and condition variables that are never used, > and initializing them would just be a slow down. Precisely. > > > - Jay > > ---------------------------------------- >> Date: Thu, 13 Jan 2011 02:37:40 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/13 02:37:40 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 >> ThreadPThread.m3 >> ThreadPThreadC.c >> >> Log message: >> Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for >> InitMutex instead of initMu to avoid deadlock between Initmutex and >> AtForkParent. >> From hosking at elego.de Thu Jan 13 06:58:48 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 6:58:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113055848.D4DF02474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 06:58:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap/UnlockHeap in case we already did this in RTCollector AtForkPrepare/AtForkParent. From jkrell at elego.de Thu Jan 13 15:58:29 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 13 Jan 2011 15:58:29 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113145829.72EAD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/13 15:58:29 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: __builtin_alloca didn't work w/o translation among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca and do the comparison by pointer equality (since gcc uses string interning) I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near anything else. From jay.krell at cornell.edu Thu Jan 13 16:00:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:00:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113145829.72EAD2474003@birch.elegosoft.com> References: <20110113145829.72EAD2474003@birch.elegosoft.com> Message-ID: Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 13 16:06:37 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:06:37 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113145829.72EAD2474003@birch.elegosoft.com>, Message-ID: Hm. I'll try the hashtable instead. - Jay From: jay.krell at cornell.edu To: jkrell at elego.de; m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 13 Jan 2011 15:00:24 +0000 Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at elego.de Thu Jan 13 19:16:48 2011 From: mika at elego.de (Mika Nystrom) Date: Thu, 13 Jan 2011 19:16:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113181648.6D80ECC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/13 19:16:48 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: updated documentation/in-line comments for thread testing program to describe design and usage of program From jkrell at elego.de Fri Jan 14 08:19:39 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 14 Jan 2011 8:19:39 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114071939.5EEB8CC10F@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/14 08:19:39 Modified files: cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: There is no need to put all/any of the builtins into a hashtable. All of the uses are very direct/special, except for m3_alloca. That is, the frontend doesn't generate regular function calls to any of them, except m3_alloca. From mika at elego.de Fri Jan 14 14:52:05 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 14:52:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114135206.1F33F2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 14:52:05 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Make diagnostic output snazzier. Now prints median and minimum ages as well as maximum age, for each category of threads. From mika at elego.de Fri Jan 14 15:05:37 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:05:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140537.688332474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:05:37 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Even snazzier: ignore exceptions that happen during setup, print diagnostics for exceptions that happen during running, and eliminate all compiler warnings. From mika at elego.de Fri Jan 14 15:09:02 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:09:02 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140902.199AD2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:09:02 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Fix comments to match code. From mika at elego.de Sat Jan 15 14:39:09 2011 From: mika at elego.de (Mika Nystrom) Date: Sat, 15 Jan 2011 14:39:09 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110115133909.E6F07CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/15 14:39:09 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Add a fourth class of threads to thread tester: thread-creator threads. From mika at elego.de Sun Jan 16 02:18:27 2011 From: mika at elego.de (Mika Nystrom) Date: Sun, 16 Jan 2011 2:18:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116011827.DD31F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/16 02:18:27 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: give the user something to look at while the program runs (also shows off deadlock well) From dabenavidesd at yahoo.es Sun Jan 16 03:27:40 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 02:27:40 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116011827.DD31F2474003@birch.elegosoft.com> Message-ID: <19786.44534.qm@web29702.mail.ird.yahoo.com> Hi all: Yes, sure just that we need also for range checks and type checks, I mean, I guess the problem are not the client programs by itself if so why do you think they crashed unsafely? The problem is to test the implementation more deeply, perhaps Tony is the best man to do that part of the job I think. However unsafe code there is guaranteed by others to be right, I tend to feel that in those cases a more detailed test compliance is needed, I mean, we don't guarantee every platform behaves exactly as we think of it. Perhaps Jay could be indicated for that part of the job, I think. Thanks in advance --- El s?b, 15/1/11, Mika Nystrom escribi?: > De: Mika Nystrom > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:18 > CVSROOT: /usr/cvs > Changes by: mika at birch. > 11/01/16 02:18:27 > > Modified files: > cm3/m3-libs/m3core/tests/thread/src/: > Main.m3 > > Log message: > give the user something to look at while > the program runs (also shows off deadlock well) > > From dabenavidesd at yahoo.es Sun Jan 16 04:36:23 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 03:36:23 +0000 (GMT) Subject: [M3commit] [M3devel] CVS Update: cm3 In-Reply-To: <19786.44534.qm@web29702.mail.ird.yahoo.com> Message-ID: <878606.72309.qm@web29713.mail.ird.yahoo.com> Hi all: The best source of a check for both cases is a test set for Modula-3 vs C threading programs. I mean what source of it might come to crash if we allow just normal range and type checking by itself on the Modula-3 programs, just C part that we don't have, I assume the Modula-3 parts touching it are thread safe as it's the collector, if a program is to crash badly, it should crash in the Modula-3 version and be unsafely crashed at a certain level on C in some cases (sort of the exceptional cases), I'm more interested that it doesn't crash on both sides, sort of being a good M3 behaved guy, that is, what it would mean is we do have a problem on the threading library implementation (not tested, unmarked exception, or uncaught ones?), given platforms behave well, that sometimes I think they do, but we don't know, that's why we need test some assertions if so (not generate the code if you want to run assembly smoothly sure). Perhaps the best approach here is just to test it right goes into C mode and then is just part of the safe modules to guard type check the bad inputs or outputs ISTYPE() is a good way of doing it if you may allow me say. Thanks in advance. --- El s?b, 15/1/11, Daniel Alejandro Benavides D. escribi?: > De: Daniel Alejandro Benavides D. > Asunto: Re: [M3devel] [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com, mika at elego.de, m3devel at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:27 > Hi all: > Yes, sure just that we need also for range checks and type > checks, I mean, I guess the problem are not the client > programs by itself if so why do you think they crashed > unsafely? > The problem is to test the implementation more deeply, > perhaps Tony is the best man to do that part of the job I > think. > However unsafe code there is guaranteed by others to be > right, I tend to feel that in those cases a more detailed > test compliance is needed, I mean, we don't guarantee every > platform behaves exactly as we think of it. Perhaps Jay > could be indicated for that part of the job, I think. > Thanks in advance > > --- El s?b, 15/1/11, Mika Nystrom > escribi?: > > > De: Mika Nystrom > > Asunto: [M3commit] CVS Update: cm3 > > Para: m3commit at elegosoft.com > > Fecha: s?bado, 15 de enero, 2011 21:18 > > CVSROOT: /usr/cvs > > Changes by: > mika at birch. > > 11/01/16 02:18:27 > > > > Modified files: > > > cm3/m3-libs/m3core/tests/thread/src/: > > Main.m3 > > > > Log message: > > give the user something to > look at while > > the program runs (also shows off deadlock well) > > > > > > > > From hosking at elego.de Sun Jan 16 20:58:37 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 20:58:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116195837.5997B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 20:58:37 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: No need to LockHeap/UnlockHeap at fork. Simply reset flags recording threads started. From hosking at elego.de Sun Jan 16 21:02:17 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:02:17 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200217.B82172474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:02:17 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: Eliminate AtForkPrepare and AtForkParent. From hosking at elego.de Sun Jan 16 21:06:48 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:06:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200648.58E012474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:06:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Reinstate initMu. LockHeap should never be called before locking any of activeMu, slotsMu, initMu, perfMu. From hosking at elego.de Sun Jan 16 22:25:21 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 22:25:21 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116212521.EEE5F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 22:25:21 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: One more deadlock between activeMu and LockHeap. SuspendOthers can be called while LockHeap, which then locks activeMu. From mika at elego.de Mon Jan 17 05:58:56 2011 From: mika at elego.de (Mika Nystrom) Date: Mon, 17 Jan 2011 5:58:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110117045856.65FE62474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/17 05:58:56 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: add a fifth type of thread---"locker" thread. From jay.krell at cornell.edu Mon Jan 17 06:42:12 2011 From: jay.krell at cornell.edu (jay.krell at cornell.edu) Date: Sun, 16 Jan 2011 21:42:12 -0800 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116195837.5997B2474003@birch.elegosoft.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> Message-ID: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). - Jay On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/16 20:58:37 > > Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 > > Log message: > No need to LockHeap/UnlockHeap at fork. > Simply reset flags recording threads started. > From hosking at cs.purdue.edu Mon Jan 17 13:55:57 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 17 Jan 2011 07:55:57 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> Message-ID: <08342311-619A-443A-9685-97E5BD6E9404@cs.purdue.edu> It gets locked in ThreadPThread atfork. Sent from my iPhone On Jan 17, 2011, at 12:42 AM, jay.krell at cornell.edu wrote: > I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). > > - Jay > > On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/16 20:58:37 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 >> >> Log message: >> No need to LockHeap/UnlockHeap at fork. >> Simply reset flags recording threads started. >> From rodney at elego.de Tue Jan 18 03:21:42 2011 From: rodney at elego.de (Rodney M. Bates) Date: Tue, 18 Jan 2011 3:21:42 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110118022143.132DC2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: rodney at birch. 11/01/18 03:21:42 Modified files: cm3/m3-sys/m3gdb/gdb/gdb/: Tag: release_branch_cm3_5_8 i386-tdep.c Log message: An incomplete fix to get results of floating type working on m3gdb-typed calls to functions. This needs extensive rework. m3gdb borrows heavily from gdb for handling floating values. But gdb has only one floating type code (TYPE_CODE_FLT) and it distinguishes the different floating types by size. This is not really sufficient for M3, because there are 3 floating types, not necessarily all the same size. New type codes for M3 have been in here for years, but many places in existing gdb code need to recognize them. Also, existing gdb printing and other handling of floating values may not be exacly right for m3gdb anyway. It might be nice to just call M3 code in, e.g., Fmt. From jkrell at elego.de Sat Jan 22 20:39:19 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 22 Jan 2011 20:39:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110122193919.A61892474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/22 20:39:19 Modified files: cm3/m3-sys/m3cc/gcc-4.5/include/: libiberty.h Log message: #include libgen.h instead of declaring basename From jkrell at elego.de Sun Jan 30 11:41:48 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 30 Jan 2011 11:41:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110130104149.4129F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/30 11:41:48 Modified files: cm3/m3-sys/m3front/src/misc/: CG.i3 Log message: remove one newline From jkrell at elego.de Mon Jan 3 14:14:25 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:14:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103131425.63E4A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:14:25 Removed files: cm3/m3-libs/m3core/src/runtime/SPARC64_SOLARIS/: RTMachine.i3 m3makefile Log message: remove unused files From jkrell at elego.de Mon Jan 3 14:26:53 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:26:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103132656.309102474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:26:53 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapStats.i3 Log message: one newline at end of file suffices From jkrell at elego.de Mon Jan 3 14:57:45 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:57:45 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103135745.B1B6A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:57:45 Modified files: cm3/m3-libs/m3core/src/runtime/ALPHA_OSF/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/SOLsun/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 RTMachine.i3 Log message: Use 64K pages everywhere -- less target dependent code, basically. The page size used to be target dependent when the garbage collector interacted with virtual memory. Now it is basically not machine dependent, except that on Windows we use VirtualAlloc, which always allocates on 64K boundaries, even if you ask for less than 64K, so allocation less than 64K ends up completely wasting memory. This could be viewed negatively as giving the Windows-dependent value to all targets. But I think it is ok. From jkrell at elego.de Mon Jan 3 15:05:36 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:05:36 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103140536.2BCBD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:05:36 Removed files: cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 RTStackASM.s RTStackC.c m3makefile Log message: This code has a high ratio of bug workarounds and reverse engineering. And it is long dead -- I believe it is for Ultrix on MIPS. Delete it. If someone brings back Ultrix (in an emulator?)... From jkrell at elego.de Mon Jan 3 15:13:04 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:13:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103141304.4E7262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:13:04 Modified files: cm3/m3-libs/m3core/src/runtime/NT386/: m3makefile cm3/m3-libs/m3core/src/runtime/common/: m3makefile Removed files: cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 Log message: use common RTMachine.i3 From jkrell at elego.de Tue Jan 4 12:21:56 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 12:21:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104112156.2F9952474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 12:21:56 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 Log message: fix warning: remove unused import RTMachine From jkrell at elego.de Tue Jan 4 13:48:34 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 13:48:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104124834.AF0222474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 13:48:34 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 cm3/m3-libs/m3core/src/C/: m3makefile cm3/m3-libs/m3core/src/C/Common/: m3makefile cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 Added files: cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 Removed files: cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile Log message: Set jumpbuf_align to 64 for all targets. We'd really like to use 2 * BYTESIZE(INTEGER) for all targets except PPC_LINUX, but that isn't expressible. This is therefore as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, and non-ideal for PPC_LINUX, roughly the same as it ever was (well, the middle end got it right, but the runtime didn't, and they do need to match; so it was seemingly wrong, but somehow worked on PPC_LINUX) In future, hopefully, compiler will inject the type instead of depending on it being declared elsewhere in Modula-3. In future, hopefully, this code will fall away on the majority of platforms/users -- i.e. if we use the gcc stack walker. But it will still stay around in some form for portability to non-gcc platforms. So injecting the type is still desirable. This removes lots of target-dependence. This has the downside of introducing an extra 4 bytes of unnecessary frame size on platforms where 4 byte alignment of jmpbuf is sufficient. (Note that we have and continue to bloat the jmpbuf for other reasons. - sometimes it was sigjmpbuf, no longe - sometimes it is plain wrong, e.g. LINUXLIBC6, still - sometimes for hypothetical interop e.g. NT <=> Interix) If RaiseActivation were one more or one less word, or if the frame has an otherwise odd number of words, the wastage should be removable by offseting the location of RaiseActivation. That is, alignment should be achievable by via hole, but via offseting the enclosing base and possibly using the hole that that creates. In either case, I'm inclined to go one step further and pass an extern const to alloca and only put a pointer to the jmpbuf in the "EF1", dramatically further eliminating target-dependence. We are already calling pthread_getspecific and setjmp, so alloca seems maybe a further reasonable deoptimization in an already slow path. Perhaps we could somehow combine the calls (not easy, given how setjmp and alloca are so special). This would presumably also address the alignment problem -- assuming alloca knows to return a pointer aligned enough for "anything", i.e. including a jmpbuf. There are still some platform-dependent Csetjmp.i3 files (NT) in order to call longjmp instead of the more common _longjmp. Testing, reading headers, and/or disasm will hopefully show that such platforms have _longjmp and it is equivalent. Soon. From jkrell at elego.de Tue Jan 4 14:04:53 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:04:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104130453.9D7152474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:04:53 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 Log message: fix comment: "efficient" => "inefficient" From jay.krell at cornell.edu Tue Jan 4 14:03:17 2011 From: jay.krell at cornell.edu (Jay K) Date: Tue, 4 Jan 2011 13:03:17 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110104124834.AF0222474003@birch.elegosoft.com> References: <20110104124834.AF0222474003@birch.elegosoft.com> Message-ID: straightforward diff attached > Date: Tue, 4 Jan 2011 13:48:34 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/04 13:48:34 > > Modified files: > cm3/m3-sys/m3middle/src/: Target.m3 > cm3/m3-libs/m3core/src/C/: m3makefile > cm3/m3-libs/m3core/src/C/Common/: m3makefile > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > Added files: > cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 > Removed files: > cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile > > Log message: > Set jumpbuf_align to 64 for all targets. > > We'd really like to use 2 * BYTESIZE(INTEGER) for all targets > except PPC_LINUX, but that isn't expressible. This is therefore > as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, > and non-ideal for PPC_LINUX, roughly the same as it ever was > (well, the middle end got it right, but the runtime didn't, > and they do need to match; so it was seemingly wrong, but > somehow worked on PPC_LINUX) > > In future, hopefully, compiler will inject the type instead > of depending on it being declared elsewhere in Modula-3. > > In future, hopefully, this code will fall away on the majority > of platforms/users -- i.e. if we use the gcc stack walker. > But it will still stay around in some form for portability > to non-gcc platforms. So injecting the type is still desirable. > > This removes lots of target-dependence. > This has the downside of introducing an extra 4 bytes of unnecessary > frame size on platforms where 4 byte alignment of jmpbuf is sufficient. > (Note that we have and continue to bloat the jmpbuf for other reasons. > - sometimes it was sigjmpbuf, no longe > - sometimes it is plain wrong, e.g. LINUXLIBC6, still > - sometimes for hypothetical interop e.g. NT <=> Interix) > > If RaiseActivation were one more or one less word, > or if the frame has an otherwise odd number of words, > the wastage should be removable by offseting the location > of RaiseActivation. That is, alignment should be achievable > by via hole, but via offseting the enclosing base and > possibly using the hole that that creates. > > In either case, I'm inclined to go one step further and pass > an extern const to alloca and only put a pointer to the jmpbuf > in the "EF1", dramatically further eliminating target-dependence. > We are already calling pthread_getspecific and setjmp, so alloca > seems maybe a further reasonable deoptimization in an already slow path. > Perhaps we could somehow combine the calls (not easy, given > how setjmp and alloca are so special). This would presumably > also address the alignment problem -- assuming alloca knows > to return a pointer aligned enough for "anything", i.e. including > a jmpbuf. > > There are still some platform-dependent Csetjmp.i3 files (NT) > in order to call longjmp instead of the more common _longjmp. > Testing, reading headers, and/or disasm will hopefully show > that such platforms have _longjmp and it is equivalent. Soon. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf64.txt URL: From jkrell at elego.de Tue Jan 4 14:14:52 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:14:52 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131452.1DA622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:14:52 Added files: cm3/scripts/config/: alloca_alignment.c Log message: program to see how aligned alloca() result is From jkrell at elego.de Tue Jan 4 14:15:11 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:15:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131511.F3A3D2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:15:11 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: show more bits From jkrell at elego.de Tue Jan 4 14:23:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:23:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104132325.5B1682474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:23:25 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: alloca.h on some platforms needed, e.g. Solaris From jkrell at elego.de Tue Jan 4 20:27:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 20:27:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104192725.362E32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 20:27:25 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: Makefile.in tree-ssa-loop.c cm3/m3-sys/m3cc/src/: clean_marker.txt Removed files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-loop-linear.c Log message: Remove tree-loop-linear optimization pass, which the gcc developers are considering removing since it is apparently broken. See http://gcc.gnu.org/ml/gcc/2011-01/msg00056.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00133.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00143.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00146.html cleanup a little graphite stuff (graphite/cloog/ppl refers to loop optimizations in gcc that are dependent upon additional libraries being available, similar to the situation with gmp/mpfr/mpc, but that they are optional even in unpatched gcc) From jkrell at elego.de Tue Jan 4 21:43:37 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:43:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204337.97F562474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:43:37 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: ipa-reference.c tree-vect-stmts.c Log message: fix warnings by removing unused function and locals From jkrell at elego.de Tue Jan 4 21:47:27 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:47:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204727.E9BB82474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:47:27 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-ssa-loop-niter.c Log message: fix some warnings, ATTRIBUTE_UNUSED on unused parameters From jkrell at elego.de Wed Jan 5 15:08:19 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:08:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105140819.DE2A1CC110@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:08:19 Modified files: cm3/m3-sys/m3back/src/: M3C.m3 Log message: flush minor change that was sitting around, not yet really in use From jkrell at elego.de Wed Jan 5 15:16:04 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:16:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141604.2D23C2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:16:04 Modified files: cm3/scripts/config/: stack_direction.c Log message: flush minor change: make it look just like m3core From jkrell at elego.de Wed Jan 5 15:17:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:17:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141751.9A9622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:17:51 Modified files: cm3/scripts/config/: stack_direction.c Log message: more like m3core From jkrell at elego.de Wed Jan 5 15:19:28 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:19:28 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141928.30CB32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:19:28 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: comments only From jkrell at elego.de Wed Jan 5 15:20:03 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:20:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142003.5C442CC123@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:20:03 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: another possible inline suppression From jkrell at elego.de Wed Jan 5 15:21:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:21:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142151.23B672474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:21:51 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: const => EXTERN_CONST This makes it mean the same thing in all C and C++ compilers. Just plain "extern const" would do the same, but that gcc warns for this correct unambiguous portable usage.. From jkrell at elego.de Wed Jan 5 15:25:37 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:25:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142537.AB0932474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:25:37 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: whitespace only, so that subsequent change lines up w/o adding the whitespace change From jkrell at elego.de Wed Jan 5 15:34:55 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:34:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105143455.087E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:34:55 Modified files: cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 Log message: use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); alloca(Csetjmp__Jumpbuf_size) to allocate jmp_buf - eliminates a large swath of target-dependent code - allows for covering up the inability to declare types with alignment > 64 bits It is, granted, a little bit slower, in an already prety slow path. Note that alloca isn't actually a function call, at least with gcc backend. From jay.krell at cornell.edu Wed Jan 5 15:37:12 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 14:37:12 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105143455.087E22474003@birch.elegosoft.com> References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf_alloca.txt URL: From jkrell at elego.de Wed Jan 5 18:32:01 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 18:32:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105173201.5A1742474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 18:32:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: Don't use __thread on Solaris. It failed to link. See: http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console From dabenavidesd at yahoo.es Wed Jan 5 19:10:27 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 18:10:27 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105173201.5A1742474003@birch.elegosoft.com> Message-ID: <167906.41482.qm@web29707.mail.ird.yahoo.com> Hi all: Are this failures linked to a trac ticket with an appropriate tag, would be a quality of service improvement to link to it automatically? I think if the failures of compiler, system compiler, compiler back end, linker, system linker or checker and/or theorem prover, we should produce automatically a ticket assigned for the "guilty" or some else if so, so one can be warned more directly and solve it accordingly, what do you think? I assume some simple changes are or can be back up if so there is a clear compile time error cause and solution. But for everything else is good? I mean might be the ideal with wiki service open we can improve documentation and process on it. Thanks in advance --- El mi?, 5/1/11, Jay Krell escribi?: > De: Jay Krell > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: mi?rcoles, 5 de enero, 2011 13:32 > CVSROOT: /usr/cvs > Changes by: > jkrell at birch. 11/01/05 18:32:01 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: > ThreadPThreadC.c > > Log message: > Don't use __thread on Solaris. > It failed to link. > See: > http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console > > From hosking at cs.purdue.edu Wed Jan 5 19:35:59 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 13:35:59 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 21:44:08 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 20:44:08 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 23:40:25 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 22:40:25 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Thu Jan 6 00:31:08 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 23:31:08 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: Message-ID: <381607.89212.qm@web29720.mail.ird.yahoo.com> Hi all: I wonder how we could make the static M3CG stack allocation tracing verified so not overflow can occur and so make a progress with that compiler obligation too. I suppose every thing we can put in the stack instead of the heap is less efficient in compiler and the checker times but in terms of execution less slower than it would without it. I recall just an experiment with the ESC to check DISPOSE statement (side effecting) instruction will not corrupt the heap with the ESC, kind of interesting for the help M3CG to disable compiler inserted useless garbage collector calls and if so usable inside the stack boundaries for checking unused stack allocated callee? for instance inside the bug commented by Mika on see: https://mail.elegosoft.com/pipermail/m3devel/2010-December/008330.html perhaps a mapping of the M3CG typed implementation if we have already a reference to that unreachable code and if so will it be called or not according to the compiler code generator, in such a case there is a on-live dynamic linking it will just like it could prove it or not to not disable those callers, we would need to automatically infer the annotations for the checker to M3CG ?-instructions and feed for the checker and prover that too. This would be useful not just for the compiler, but for the programmer too, don't you think? Also this would be straightforward to demonstrative of a program that is not to overflow or underflow by popping out anyhow, another missing check in current compilers technology as of what I currently know. Besides that one must check the arithmetic overflow, that would need more of the ESC normal technology by now, though we could explicitly check for it in the searched errors too, again typing the M3CG ?-instructions will gave some of the neeeded info I guess and by emulating ALU logic we could also warn proof that anything would happen in some point if contracts are fulfilled. ?? Thanks in advance --- El mi?, 5/1/11, Jay K escribi?: De: Jay K Asunto: Re: [M3commit] CVS Update: cm3 Para: "Tony" CC: m3commit at elegosoft.com Fecha: mi?rcoles, 5 de enero, 2011 17:40 I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. ?- Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 #yiv448101372 .yiv448101372ExternalClass .yiv448101372ecxhmmessage P {padding:0px;} #yiv448101372 .yiv448101372ExternalClass body.yiv448101372ecxhmmessage {font-size:10pt;font-family:Tahoma;} I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? ?I don't know what has been done here without diving into the diff. Antony Hosking?|?Associate Professor?| Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice?+1 765 494 6001 |?Mobile?+1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To:?m3commit at elegosoft.com > From:?jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 >? > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 >? > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3? > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3? > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c? > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c? > cm3/m3-sys/m3front/src/misc/: Marker.m3? > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3? > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3? >? > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) >? > to allocate jmp_buf >? > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits >? > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. >? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 01:17:01 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:17:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106001701.1620F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:17:00 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Main.m3 m3makefile Log message: a test case from Mika currently results in: new source -> compiling Main.m3 "../Main.m3", line 21: warning: potentially unhandled exception: OSError.E "../Main.m3", line 18: warning: potentially unhandled exception: Thread.Alerted "../Main.m3", line 16: warning: not used (DumpOne) "../Main.m3", line 15: warning: not used (DumpMatching) 4 warnings encountered ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [66]) (const_int 0 [0x0])) (set (reg:SI 1 dx [64]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 1 dx [64]))) (set (reg:SI 4 si [65]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 4 si [65]))) (set (mem/s/c:BLK (reg:SI 1 dx [64]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg:SI 4 si [65]) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [66])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [66]) (expr_list:REG_UNUSED (reg:SI 4 si [65]) (expr_list:REG_UNUSED (reg:SI 1 dx [64]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. m3_backend => 4 m3cc (aka cm3cg) failed compiling: Main.mc compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:25:08 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:25:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002508.623F92474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:25:08 Added files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 m3makefile Log message: another test case from Mika jbook2:p250 jay$ cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 1: 1 code generation error 1 error encountered compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:26:15 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:26:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002615.77E782474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:26:15 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: slightly simpler, same error From hosking at cs.purdue.edu Thu Jan 6 02:21:11 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:21:11 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: <3AC78E33-81AB-49EF-B566-468EF601BC36@cs.purdue.edu> Do you alloca on every TRY or once in procedures that have a TRY? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 3:44 PM, Jay K wrote: > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 02:23:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:23:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote: > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:25:03 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:25:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106012503.90C392474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:25:03 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: much simpler, same error From jay.krell at cornell.edu Thu Jan 6 02:33:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 01:33:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:33:51 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:33:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013351.4AB262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:33:51 Modified files: cm3/m3-sys/m3tests/src/: Test.i3 TestC.c Log message: fix now that Csetjmp is unsafe, and that we don't need to check the size of jmpbuf From jkrell at elego.de Thu Jan 6 02:38:38 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:38:38 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013838.D102B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:38:38 Added files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 m3makefile Log message: starting some new test code to nail down try/finally/except/lock stuff not yet done, taking short break From hosking at cs.purdue.edu Thu Jan 6 02:49:24 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:49:24 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote: > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 03:08:47 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 02:08:47 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 03:14:17 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 21:14:17 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 03:32:11 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 3:32:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106023211.9CC57CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 03:32:11 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: work in progress From jkrell at elego.de Thu Jan 6 04:42:30 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 4:42:30 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106034231.3E0E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 04:42:30 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p250/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p251/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 Log message: perhaps slightly controversial: add new tests in old branch This is a little easier to test/compare and the downside should be negligible -- downside of polluting history. From jay.krell at cornell.edu Thu Jan 6 05:52:33 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 04:52:33 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 07:02:26 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 06:02:26 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 08:18:41 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 8:18:41 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106071841.7E2072474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 08:18:41 Modified files: cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/runtime/ex_stack/: RTExStack.m3 Log message: comments only; in particular put in "see also" indicating these files describe each other From hosking at cs.purdue.edu Thu Jan 6 15:19:36 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:19:36 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: <6DAAF11E-4EA3-4D9E-BFBE-4B15D2B873F5@cs.purdue.edu> No, if there are n static TRY block sites, then up to n calls to alloca is OK. I am assuming you test for NIL at each site and alloca only if NIL. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 11:52 PM, Jay K wrote: > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 15:22:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:22:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. 2. If not, then alloca and save its pointer in the local variable 3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 17:29:44 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 17:29:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106162944.39C442474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 17:29:44 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: more tests From jay.krell at cornell.edu Thu Jan 6 17:35:43 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 16:35:43 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. I guess, really, it is EF1, EF2, etc. So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. something like: PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; => void F1() { jmp_buf* jb = 0; EF1 a,b,c; setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 do stuff 1... setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 do stuff 2... setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 do stuff 3... } (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) Still, something I can't pin down strikes me as too simple here. If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. That doesn't seem adequate. What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? It won't know where to resume, right? It's just keep longjmping to the same place. In the Visual C++ runtime, there is "local unwind" and "global unwind". "local unwind" is like, "within the same functin", "global unwind" is across functions. I think somehow that is related here. e.g. how would you ensure forward progress in this: EXCEPTION E1; EXCEPTION E2; EXCEPTION E3; PROCEDURE F4() RAISES ANY = CONST Function = "F4 "; BEGIN Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); RAISE E1; EXCEPT ELSE RAISE E2; END; EXCEPT ELSE RAISE E3; END; EXCEPT ELSE END; END F4; Oddly in my test p251, the stack depth is not increased by TRY. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Thu, 6 Jan 2011 09:22:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL.2. If not, then alloca and save its pointer in the local variable3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 18:08:47 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 18:08:47 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106170847.442592474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 18:08:47 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: aha! loop with try, not good From hosking at cs.purdue.edu Thu Jan 6 19:52:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 13:52:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> You can't have one jmpbuf per procedure. You need one per TRY scope, since they can be nested. On Jan 6, 2011, at 11:35 AM, Jay K wrote: > Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 20:00:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 19:00:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: I believe you can, but it'd take significant work in the frontend. The jmpbuf should identify merely which procedure/frame to return to. There would also be a volatile local integer, that gets altered at certain points through the function. When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. Instead of setjmp, the compiler pessimizes appropriately. So the result is that a function with one or more tries, or one or more locals with destructors, puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate where in the function it is. If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. It is more work through, granted, I can understand that. And given that we have a much better option for many platforms, the payoff would be reduced. Anyway, I'm trying what you say, like for TRY within a loop. I should point out that alloca has an extra inefficiency vs. the previous approach. It aligns more. So it is using more stack than the other way. And it might pessimize codegen in other ways. The gcc code appears somewhat similar..I think the tables merely describe, again, which function/frame to return to, and that within the frame there is a local integer to determine more precisely what to do. I'm not sure. I saw mention of a switch. ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 13:52:42 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You can't have one jmpbuf per procedure. You need one per TRY scope, > since they can be nested. > > > > On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > Hm. How do I single instance the "EF1"? The current code allocates a > local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store > it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how > to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the > existance of the ternary operator, and that it only evaluates one side > or the other, and that assignment is expression..I quite like those > features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of > additional progress, you only ever know the last place you were in a > function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and > then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the > same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is > across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking > if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the > compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation > is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one > setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then > live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly > possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your > point is, you'd rather have n locals, which the backend automatically > merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to > setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if > setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific > per function > - The calls to alloca could be merged. The frontend could keep track > of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? > Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY > block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of > the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, > it calls setjmp once. > And then, it should have one volatile integer, that in a sense > represents the line number. > But not really. It's like, every time you cross a TRY, the integer is > incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the > value can be stored. > And then there is a maximum of one one handler per function, it > switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix > it -- check for NIL. > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > are allocating on every TRY where previously the storage was statically > allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is > actually fairly small to read. > I understand it is definitely less efficient, a few more instructions > for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change > is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there > probably is a function call there. > > - Jay > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in > EF1 is now allocated with alloca, and a pointer stored. It is > definitely a bit less efficient, but the significant advantage is > frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to > more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > to align to 16 bytes. I don't have an HPUX machine currently to see if > the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack > walker. I wanted to do this first though, while more targets using > setjmp. > > - Jay/phone > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what > has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > > From hosking at cs.purdue.edu Thu Jan 6 20:11:04 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 14:11:04 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > I believe you can, but it'd take significant work in the frontend. > The jmpbuf should identify merely which procedure/frame to return to. > There would also be a volatile local integer, that gets altered at certain points through the function. > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > Instead of setjmp, the compiler pessimizes appropriately. > > > So the result is that a function with one or more tries, or one or more locals with destructors, > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > where in the function it is. > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > It is more work through, granted, I can understand that. > And given that we have a much better option for many platforms, the payoff would be reduced. > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > It aligns more. So it is using more stack than the other way. > And it might pessimize codegen in other ways. > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > function/frame to return to, and that within the frame there is a local integer to determine > more precisely what to do. I'm not sure. I saw mention of a switch. > > > - Jay > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 13:52:42 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> You can't have one jmpbuf per procedure. You need one per TRY scope, >> since they can be nested. >> >> >> >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >> >> Hm. How do I single instance the "EF1"? The current code allocates a >> local "EF1" for each try. >> I guess, really, it is EF1, EF2, etc. >> So there should be a separate local for the jmpbuf pointer, and store >> it in each EF* block? >> How do I make just one jmpbuf pointer? I couldn't easily figure out how >> to in the front end, I need to read it more. >> >> something like: >> >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >> END END END END F1; >> => >> >> void F1() >> { >> jmp_buf* jb = 0; >> EF1 a,b,c; >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >> do stuff 1... >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >> do stuff 2... >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >> do stuff 3... >> } >> >> (The actual syntactic and semantic correctness of this code -- the >> existance of the ternary operator, and that it only evaluates one side >> or the other, and that assignment is expression..I quite like those >> features....) >> >> >> Still, something I can't pin down strikes me as too simple here. >> >> >> If there is just one setjmp, and no integer(s) to keep track of >> additional progress, you only ever know the last place you were in a >> function. >> That doesn't seem adequate. >> >> >> What if a function raises an exception, catches it within itself, and >> then raises something else, and then wants to catch that? >> It won't know where to resume, right? It's just keep longjmping to the >> same place. >> >> >> In the Visual C++ runtime, there is "local unwind" and "global unwind". >> "local unwind" is like, "within the same functin", "global unwind" is >> across functions. >> I think somehow that is related here. >> >> >> e.g. how would you ensure forward progress in this: >> >> >> EXCEPTION E1; >> EXCEPTION E2; >> EXCEPTION E3; >> >> >> PROCEDURE F4() RAISES ANY = >> CONST Function = "F4 "; >> BEGIN >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> RAISE E1; >> EXCEPT ELSE >> RAISE E2; >> END; >> EXCEPT ELSE >> RAISE E3; >> END; >> EXCEPT ELSE >> END; >> END F4; >> >> >> Oddly in my test p251, the stack depth is not increased by TRY. >> >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 09:22:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I am OK with what you have currently: >> >> At each TRY: >> >> 1. Check if a corresponding alloca block has been allocated by checking >> if the corresponding local variable is NIL. >> 2. If not, then alloca and save its pointer in the local variable >> 3. Execute the try block. >> >> As you say, alloca should turn into an inline operation using the >> compiler's builtin implementation of alloca. >> >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >> >>> Code size will suffer. >> >> >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >> I thought it'd only be one call. I didn't realize our implementation >> is as poor as it is, since a better but still >> portable implementation doesn't seem too too difficult. >> >> >> Can we maybe do the optimizations I indicate -- no more than one >> setjmp/alloca/pushframe per function? >> Using a local integer to record the position within the function? >> >> >> Or just give me a week or few to get stack walking working and then >> live the regression on other targets? >> (NT386 isn't likely to get stack walking, though it *is* certainly >> possible; NT does have a decent runtime here..) >> >> >> It *is* nice to not have have the frontend know about jmpbuf size. >> >> >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >> It doesn't work for intra-function jumps, only inter-function. >> >> >> - Jay >> >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 04:52:33 +0000 >> >> Ah..I'm doing more comparisons of release vs. head...but..I guess your >> point is, you'd rather have n locals, which the backend automatically >> merges, than n calls to alloca? >> It's not a huge difference -- there are still going to be n calls to >> setjmp and n calls to pthread_getspecific. >> The alloca calls will be dwarfed. >> Code size will suffer. >> >> >> And, even so, there are plenty of optimizations to be had, even if >> setjmp/pthread_getspecific is used. >> >> >> - It could make a maximum of one call to setjmp/pthread_getspecific >> per function >> - The calls to alloca could be merged. The frontend could keep track >> of how many calls it makes per function, >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >> >> >> So, yes, given my current understanding, it is progress. >> The target-dependence is not worth it, imho. >> I'll still do some comparisons to release. >> >> >> I'll still be looking into using the gcc unwinder relatively soon. >> >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 21:14:17 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >> >> Tony, um..well, um.. first, isn't that how it already worked maybe? >> Declaring a new local EF1 for each TRY? It looks like it. >> I'll do more testing. >> >> Yes, it did. I assume you simply have a local variable for each TRY >> block that is a pointer now instead of a jmp_buf. Should be OK. >> >> >> So the additional inefficiency is multiplied the same as the rest of >> the preexisting inefficiency. >> And the preexisting inefficiency is way more than the increase. >> >> And second, either way, it could be better. >> >> Basically, the model should be, that if a function has any try or lock, >> it calls setjmp once. >> And then, it should have one volatile integer, that in a sense >> represents the line number. >> But not really. It's like, every time you cross a TRY, the integer is >> incremented, every time you >> cross a finally or unlock, the integer is decremented. Or rather, the >> value can be stored. >> And then there is a maximum of one one handler per function, it >> switches on the integer >> to decide where it got into the function and what it should do. >> >> This is how other compilers work and it is a fairly simple sensible approach. >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:49:24 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Note that you need a different jmpbuf for each nested TRY! >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >> >> oops, that's not how I thought it worked. I'll do more testing and fix >> it -- check for NIL. >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:23:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >> are allocating on every TRY where previously the storage was statically >> allocated. Do you really think this is progress? >> >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >> >> I've back with full keyboard if more explanation needed. The diff is >> actually fairly small to read. >> I understand it is definitely less efficient, a few more instructions >> for every try/lock. >> No extra function call, at least with gcc backend. >> I haven't tested NT386 yet. Odds are so/so that it works -- the change >> is written so that it should work >> but I have to test it to be sure, will to roughly tonight. And there >> probably is a function call there. >> >> - Jay >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:44:08 +0000 >> CC: m3commit at elegosoft.com >> Subject: Re: [M3commit] CVS Update: cm3 >> >> I only have phone right now. I think it is fairly clear: the jumpbuf in >> EF1 is now allocated with alloca, and a pointer stored. It is >> definitely a bit less efficient, but the significant advantage is >> frontend no longer needs to know the size or alignment of a jumpbuf. >> >> >> As well, there is no longer the problem regarding jumpbuf aligned to >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >> to align to 16 bytes. I don't have an HPUX machine currently to see if >> the problem is addressed there. >> >> >> The inefficiency of course can be dramatically mitigated via a stack >> walker. I wanted to do this first though, while more targets using >> setjmp. >> >> - Jay/phone >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 13:35:59 -0500 >> CC: jkrell at elego.de; m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Can you provide a more descriptive checkin comment? I don't know what >> has been done here without diving into the diff. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >> >> diff attached >> >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>> To: m3commit at elegosoft.com >>> From: jkrell at elego.de >>> Subject: [M3commit] CVS Update: cm3 >>> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>> >>> Log message: >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>> alloca(Csetjmp__Jumpbuf_size) >>> >>> to allocate jmp_buf >>> >>> - eliminates a large swath of target-dependent code >>> - allows for covering up the inability to declare >>> types with alignment > 64 bits >>> >>> It is, granted, a little bit slower, in an already prety slow path. >>> Note that alloca isn't actually a function call, at least with gcc backend. >>> >> >> >> >> >> >> >> >> >> >> >> >> > From jay.krell at cornell.edu Thu Jan 6 21:33:21 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:33:21 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: Ok. Do you know where to initialize the jmpbuf to NIL? I have a diff that "works" (ie: doesn't crash) and is *close* to correct, it checks for NIL and branches around the alloca for non-NIL, but it also initializes to NIL repeatedly, so no change effectively. ? Index: misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.7 diff -u -w -r1.7 Marker.m3 --- misc/Marker.m3??? 5 Jan 2011 14:34:54 -0000??? 1.7 +++ misc/Marker.m3??? 6 Jan 2011 20:32:00 -0000 @@ -233,6 +233,7 @@ ? ?PROCEDURE CaptureState (frame: CG.Var;? handler: CG.Label) = ?? VAR new: BOOLEAN; +????? label := CG.Next_label (); ?? BEGIN ???? (* int setjmp(void* ); *) ???? IF (setjmp = NIL) THEN @@ -263,18 +264,25 @@ ???????????????????????????????????????? Target.Word.cg_type, 0); ???? END; ???? +??? (* IF frame.jmpbuf = NIL THEN *) + +????? CG.Load_nil (); +????? CG.Load_addr (frame, M3RT.EF1_jmpbuf); +????? CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); + ???? (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) ???? CG.Start_call_direct (alloca, 0, Target.Address.cg_type); ???? CG.Load_int (Target.Word.cg_type, Jumpbuf_size); ???? CG.Pop_param (Target.Word.cg_type); ???? CG.Call_direct (alloca, Target.Address.cg_type); -??? CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -????????????? Target.Address.cg_type); +????? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + +??? (* END *) +??? CG.Set_label (label); ? ???? (* setmp(frame.jmpbuf) *) ???? CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); -??? CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -???????????? Target.Address.cg_type); +??? CG.Load_addr (frame, M3RT.EF1_jmpbuf); ???? CG.Pop_param (CG.Type.Addr); ???? CG.Call_direct (setjmp, Target.Integer.cg_type); ???? CG.If_true (handler, CG.Never); cvs diff: Diffing stmts Index: stmts/TryFinStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v retrieving revision 1.6 diff -u -w -r1.6 TryFinStmt.m3 --- stmts/TryFinStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.6 +++ stmts/TryFinStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -299,6 +299,10 @@ ???? CG.Load_nil (); ???? CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? l := CG.Next_label (3); ???? CG.Set_label (l, barrier := TRUE); ???? Marker.PushFrame (frame, M3RT.HandlerClass.Finally); Index: stmts/TryStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v retrieving revision 1.3 diff -u -w -r1.3 TryStmt.m3 --- stmts/TryStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.3 +++ stmts/TryStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -10,7 +10,7 @@ ? ?IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; ?IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; -IMPORT Scanner, ESet, Target, M3RT, Tracer; +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; ?FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; ? ?TYPE @@ -411,6 +411,10 @@ ???? CG.Store_addr (frame, M3RT.EF1_exception); ???? ***********************************************) ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? IF (p.hasElse) THEN ?????? Marker.PushTryElse (l, l+1, frame); ?????? Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); The set_label before one of the PushEFrames could be moved down a bit, to after the NIL initialization, and that'd fix some cases, but I think not all. Thanks, - Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 14:11:04 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > > > > I believe you can, but it'd take significant work in the frontend. > > The jmpbuf should identify merely which procedure/frame to return to. > > There would also be a volatile local integer, that gets altered at certain points through the function. > > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > Instead of setjmp, the compiler pessimizes appropriately. > > > > > > So the result is that a function with one or more tries, or one or more locals with destructors, > > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > where in the function it is. > > > > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > > > > It is more work through, granted, I can understand that. > > And given that we have a much better option for many platforms, the payoff would be reduced. > > > > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > > It aligns more. So it is using more stack than the other way. > > And it might pessimize codegen in other ways. > > > > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > > function/frame to return to, and that within the frame there is a local integer to determine > > more precisely what to do. I'm not sure. I saw mention of a switch. > > > > > > - Jay > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> You can't have one jmpbuf per procedure. You need one per TRY scope, > >> since they can be nested. > >> > >> > >> > >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >> > >> Hm. How do I single instance the "EF1"? The current code allocates a > >> local "EF1" for each try. > >> I guess, really, it is EF1, EF2, etc. > >> So there should be a separate local for the jmpbuf pointer, and store > >> it in each EF* block? > >> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >> to in the front end, I need to read it more. > >> > >> something like: > >> > >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >> END END END END F1; > >> => > >> > >> void F1() > >> { > >> jmp_buf* jb = 0; > >> EF1 a,b,c; > >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >> do stuff 1... > >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >> do stuff 2... > >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >> do stuff 3... > >> } > >> > >> (The actual syntactic and semantic correctness of this code -- the > >> existance of the ternary operator, and that it only evaluates one side > >> or the other, and that assignment is expression..I quite like those > >> features....) > >> > >> > >> Still, something I can't pin down strikes me as too simple here. > >> > >> > >> If there is just one setjmp, and no integer(s) to keep track of > >> additional progress, you only ever know the last place you were in a > >> function. > >> That doesn't seem adequate. > >> > >> > >> What if a function raises an exception, catches it within itself, and > >> then raises something else, and then wants to catch that? > >> It won't know where to resume, right? It's just keep longjmping to the > >> same place. > >> > >> > >> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >> "local unwind" is like, "within the same functin", "global unwind" is > >> across functions. > >> I think somehow that is related here. > >> > >> > >> e.g. how would you ensure forward progress in this: > >> > >> > >> EXCEPTION E1; > >> EXCEPTION E2; > >> EXCEPTION E3; > >> > >> > >> PROCEDURE F4() RAISES ANY = > >> CONST Function = "F4 "; > >> BEGIN > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> RAISE E1; > >> EXCEPT ELSE > >> RAISE E2; > >> END; > >> EXCEPT ELSE > >> RAISE E3; > >> END; > >> EXCEPT ELSE > >> END; > >> END F4; > >> > >> > >> Oddly in my test p251, the stack depth is not increased by TRY. > >> > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> I am OK with what you have currently: > >> > >> At each TRY: > >> > >> 1. Check if a corresponding alloca block has been allocated by checking > >> if the corresponding local variable is NIL. > >> 2. If not, then alloca and save its pointer in the local variable > >> 3. Execute the try block. > >> > >> As you say, alloca should turn into an inline operation using the > >> compiler's builtin implementation of alloca. > >> > >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >> > >>> Code size will suffer. > >> > >> > >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >> I thought it'd only be one call. I didn't realize our implementation > >> is as poor as it is, since a better but still > >> portable implementation doesn't seem too too difficult. > >> > >> > >> Can we maybe do the optimizations I indicate -- no more than one > >> setjmp/alloca/pushframe per function? > >> Using a local integer to record the position within the function? > >> > >> > >> Or just give me a week or few to get stack walking working and then > >> live the regression on other targets? > >> (NT386 isn't likely to get stack walking, though it *is* certainly > >> possible; NT does have a decent runtime here..) > >> > >> > >> It *is* nice to not have have the frontend know about jmpbuf size. > >> > >> > >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >> It doesn't work for intra-function jumps, only inter-function. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >> > >> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >> point is, you'd rather have n locals, which the backend automatically > >> merges, than n calls to alloca? > >> It's not a huge difference -- there are still going to be n calls to > >> setjmp and n calls to pthread_getspecific. > >> The alloca calls will be dwarfed. > >> Code size will suffer. > >> > >> > >> And, even so, there are plenty of optimizations to be had, even if > >> setjmp/pthread_getspecific is used. > >> > >> > >> - It could make a maximum of one call to setjmp/pthread_getspecific > >> per function > >> - The calls to alloca could be merged. The frontend could keep track > >> of how many calls it makes per function, > >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >> > >> > >> So, yes, given my current understanding, it is progress. > >> The target-dependence is not worth it, imho. > >> I'll still do some comparisons to release. > >> > >> > >> I'll still be looking into using the gcc unwinder relatively soon. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >> > >> Tony, um..well, um.. first, isn't that how it already worked maybe? > >> Declaring a new local EF1 for each TRY? It looks like it. > >> I'll do more testing. > >> > >> Yes, it did. I assume you simply have a local variable for each TRY > >> block that is a pointer now instead of a jmp_buf. Should be OK. > >> > >> > >> So the additional inefficiency is multiplied the same as the rest of > >> the preexisting inefficiency. > >> And the preexisting inefficiency is way more than the increase. > >> > >> And second, either way, it could be better. > >> > >> Basically, the model should be, that if a function has any try or lock, > >> it calls setjmp once. > >> And then, it should have one volatile integer, that in a sense > >> represents the line number. > >> But not really. It's like, every time you cross a TRY, the integer is > >> incremented, every time you > >> cross a finally or unlock, the integer is decremented. Or rather, the > >> value can be stored. > >> And then there is a maximum of one one handler per function, it > >> switches on the integer > >> to decide where it got into the function and what it should do. > >> > >> This is how other compilers work and it is a fairly simple sensible approach. > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Note that you need a different jmpbuf for each nested TRY! > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >> > >> oops, that's not how I thought it worked. I'll do more testing and fix > >> it -- check for NIL. > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >> are allocating on every TRY where previously the storage was statically > >> allocated. Do you really think this is progress? > >> > >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >> > >> I've back with full keyboard if more explanation needed. The diff is > >> actually fairly small to read. > >> I understand it is definitely less efficient, a few more instructions > >> for every try/lock. > >> No extra function call, at least with gcc backend. > >> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >> is written so that it should work > >> but I have to test it to be sure, will to roughly tonight. And there > >> probably is a function call there. > >> > >> - Jay > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >> CC: m3commit at elegosoft.com > >> Subject: Re: [M3commit] CVS Update: cm3 > >> > >> I only have phone right now. I think it is fairly clear: the jumpbuf in > >> EF1 is now allocated with alloca, and a pointer stored. It is > >> definitely a bit less efficient, but the significant advantage is > >> frontend no longer needs to know the size or alignment of a jumpbuf. > >> > >> > >> As well, there is no longer the problem regarding jumpbuf aligned to > >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >> to align to 16 bytes. I don't have an HPUX machine currently to see if > >> the problem is addressed there. > >> > >> > >> The inefficiency of course can be dramatically mitigated via a stack > >> walker. I wanted to do this first though, while more targets using > >> setjmp. > >> > >> - Jay/phone > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Can you provide a more descriptive checkin comment? I don't know what > >> has been done here without diving into the diff. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >> > >> diff attached > >> > >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>> To: m3commit at elegosoft.com > >>> From: jkrell at elego.de > >>> Subject: [M3commit] CVS Update: cm3 > >>> > >>> CVSROOT: /usr/cvs > >>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>> > >>> Modified files: > >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>> > >>> Log message: > >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>> alloca(Csetjmp__Jumpbuf_size) > >>> > >>> to allocate jmp_buf > >>> > >>> - eliminates a large swath of target-dependent code > >>> - allows for covering up the inability to declare > >>> types with alignment > 64 bits > >>> > >>> It is, granted, a little bit slower, in an already prety slow path. > >>> Note that alloca isn't actually a function call, at least with gcc backend. > >>> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > > > From jkrell at elego.de Thu Jan 6 21:40:16 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 21:40:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106204016.8C4BF2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 21:40:16 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: use convenience Load/Store_addr instead of Load/Store From hosking at cs.purdue.edu Thu Jan 6 21:42:33 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:42:33 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> I don't understand what you mean by "initializes to NIL". How are you creating the frame variable? If you do it properly the language semantics will cause it be initialized to NIL automatically. On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > Ok. > Do you know where to initialize the jmpbuf to NIL? > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > it checks for NIL and branches around the alloca for non-NIL, but it > also initializes to NIL repeatedly, so no change effectively. > > > Index: misc/Marker.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > retrieving revision 1.7 > diff -u -w -r1.7 Marker.m3 > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > @@ -233,6 +233,7 @@ > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > VAR new: BOOLEAN; > + label := CG.Next_label (); > BEGIN > (* int setjmp(void* ); *) > IF (setjmp = NIL) THEN > @@ -263,18 +264,25 @@ > Target.Word.cg_type, 0); > END; > > + (* IF frame.jmpbuf = NIL THEN *) > + > + CG.Load_nil (); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > + > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > CG.Pop_param (Target.Word.cg_type); > CG.Call_direct (alloca, Target.Address.cg_type); > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > + (* END *) > + CG.Set_label (label); > > (* setmp(frame.jmpbuf) *) > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > CG.Pop_param (CG.Type.Addr); > CG.Call_direct (setjmp, Target.Integer.cg_type); > CG.If_true (handler, CG.Never); > cvs diff: Diffing stmts > Index: stmts/TryFinStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > retrieving revision 1.6 > diff -u -w -r1.6 TryFinStmt.m3 > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -299,6 +299,10 @@ > CG.Load_nil (); > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > l := CG.Next_label (3); > CG.Set_label (l, barrier := TRUE); > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > Index: stmts/TryStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > retrieving revision 1.3 > diff -u -w -r1.3 TryStmt.m3 > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -10,7 +10,7 @@ > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > TYPE > @@ -411,6 +411,10 @@ > CG.Store_addr (frame, M3RT.EF1_exception); > ***********************************************) > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > IF (p.hasElse) THEN > Marker.PushTryElse (l, l+1, frame); > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > The set_label before one of the PushEFrames could be moved down a bit, > to after the NIL initialization, and that'd fix some cases, but I think not all. > > Thanks, > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 14:11:04 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >> >>> >>> I believe you can, but it'd take significant work in the frontend. >>> The jmpbuf should identify merely which procedure/frame to return to. >>> There would also be a volatile local integer, that gets altered at certain points through the function. >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>> Instead of setjmp, the compiler pessimizes appropriately. >>> >>> >>> So the result is that a function with one or more tries, or one or more locals with destructors, >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>> where in the function it is. >>> >>> >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>> >>> >>> It is more work through, granted, I can understand that. >>> And given that we have a much better option for many platforms, the payoff would be reduced. >>> >>> >>> Anyway, I'm trying what you say, like for TRY within a loop. >>> >>> >>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>> It aligns more. So it is using more stack than the other way. >>> And it might pessimize codegen in other ways. >>> >>> >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>> function/frame to return to, and that within the frame there is a local integer to determine >>> more precisely what to do. I'm not sure. I saw mention of a switch. >>> >>> >>> - Jay >>> >>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>> since they can be nested. >>>> >>>> >>>> >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>> >>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>> local "EF1" for each try. >>>> I guess, really, it is EF1, EF2, etc. >>>> So there should be a separate local for the jmpbuf pointer, and store >>>> it in each EF* block? >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>> to in the front end, I need to read it more. >>>> >>>> something like: >>>> >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>> END END END END F1; >>>> => >>>> >>>> void F1() >>>> { >>>> jmp_buf* jb = 0; >>>> EF1 a,b,c; >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>> do stuff 1... >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>> do stuff 2... >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>> do stuff 3... >>>> } >>>> >>>> (The actual syntactic and semantic correctness of this code -- the >>>> existance of the ternary operator, and that it only evaluates one side >>>> or the other, and that assignment is expression..I quite like those >>>> features....) >>>> >>>> >>>> Still, something I can't pin down strikes me as too simple here. >>>> >>>> >>>> If there is just one setjmp, and no integer(s) to keep track of >>>> additional progress, you only ever know the last place you were in a >>>> function. >>>> That doesn't seem adequate. >>>> >>>> >>>> What if a function raises an exception, catches it within itself, and >>>> then raises something else, and then wants to catch that? >>>> It won't know where to resume, right? It's just keep longjmping to the >>>> same place. >>>> >>>> >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>> "local unwind" is like, "within the same functin", "global unwind" is >>>> across functions. >>>> I think somehow that is related here. >>>> >>>> >>>> e.g. how would you ensure forward progress in this: >>>> >>>> >>>> EXCEPTION E1; >>>> EXCEPTION E2; >>>> EXCEPTION E3; >>>> >>>> >>>> PROCEDURE F4() RAISES ANY = >>>> CONST Function = "F4 "; >>>> BEGIN >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> RAISE E1; >>>> EXCEPT ELSE >>>> RAISE E2; >>>> END; >>>> EXCEPT ELSE >>>> RAISE E3; >>>> END; >>>> EXCEPT ELSE >>>> END; >>>> END F4; >>>> >>>> >>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>> >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> I am OK with what you have currently: >>>> >>>> At each TRY: >>>> >>>> 1. Check if a corresponding alloca block has been allocated by checking >>>> if the corresponding local variable is NIL. >>>> 2. If not, then alloca and save its pointer in the local variable >>>> 3. Execute the try block. >>>> >>>> As you say, alloca should turn into an inline operation using the >>>> compiler's builtin implementation of alloca. >>>> >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>> >>>>> Code size will suffer. >>>> >>>> >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>> I thought it'd only be one call. I didn't realize our implementation >>>> is as poor as it is, since a better but still >>>> portable implementation doesn't seem too too difficult. >>>> >>>> >>>> Can we maybe do the optimizations I indicate -- no more than one >>>> setjmp/alloca/pushframe per function? >>>> Using a local integer to record the position within the function? >>>> >>>> >>>> Or just give me a week or few to get stack walking working and then >>>> live the regression on other targets? >>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>> possible; NT does have a decent runtime here..) >>>> >>>> >>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>> >>>> >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>> It doesn't work for intra-function jumps, only inter-function. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>> >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>> point is, you'd rather have n locals, which the backend automatically >>>> merges, than n calls to alloca? >>>> It's not a huge difference -- there are still going to be n calls to >>>> setjmp and n calls to pthread_getspecific. >>>> The alloca calls will be dwarfed. >>>> Code size will suffer. >>>> >>>> >>>> And, even so, there are plenty of optimizations to be had, even if >>>> setjmp/pthread_getspecific is used. >>>> >>>> >>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>> per function >>>> - The calls to alloca could be merged. The frontend could keep track >>>> of how many calls it makes per function, >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>> >>>> >>>> So, yes, given my current understanding, it is progress. >>>> The target-dependence is not worth it, imho. >>>> I'll still do some comparisons to release. >>>> >>>> >>>> I'll still be looking into using the gcc unwinder relatively soon. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>> >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>> Declaring a new local EF1 for each TRY? It looks like it. >>>> I'll do more testing. >>>> >>>> Yes, it did. I assume you simply have a local variable for each TRY >>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>> >>>> >>>> So the additional inefficiency is multiplied the same as the rest of >>>> the preexisting inefficiency. >>>> And the preexisting inefficiency is way more than the increase. >>>> >>>> And second, either way, it could be better. >>>> >>>> Basically, the model should be, that if a function has any try or lock, >>>> it calls setjmp once. >>>> And then, it should have one volatile integer, that in a sense >>>> represents the line number. >>>> But not really. It's like, every time you cross a TRY, the integer is >>>> incremented, every time you >>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>> value can be stored. >>>> And then there is a maximum of one one handler per function, it >>>> switches on the integer >>>> to decide where it got into the function and what it should do. >>>> >>>> This is how other compilers work and it is a fairly simple sensible approach. >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Note that you need a different jmpbuf for each nested TRY! >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>> >>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>> it -- check for NIL. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>> are allocating on every TRY where previously the storage was statically >>>> allocated. Do you really think this is progress? >>>> >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>> >>>> I've back with full keyboard if more explanation needed. The diff is >>>> actually fairly small to read. >>>> I understand it is definitely less efficient, a few more instructions >>>> for every try/lock. >>>> No extra function call, at least with gcc backend. >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>> is written so that it should work >>>> but I have to test it to be sure, will to roughly tonight. And there >>>> probably is a function call there. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>> CC: m3commit at elegosoft.com >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>> definitely a bit less efficient, but the significant advantage is >>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>> >>>> >>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>> the problem is addressed there. >>>> >>>> >>>> The inefficiency of course can be dramatically mitigated via a stack >>>> walker. I wanted to do this first though, while more targets using >>>> setjmp. >>>> >>>> - Jay/phone >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Can you provide a more descriptive checkin comment? I don't know what >>>> has been done here without diving into the diff. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>> >>>> diff attached >>>> >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>> To: m3commit at elegosoft.com >>>>> From: jkrell at elego.de >>>>> Subject: [M3commit] CVS Update: cm3 >>>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>> >>>>> Log message: >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>> alloca(Csetjmp__Jumpbuf_size) >>>>> >>>>> to allocate jmp_buf >>>>> >>>>> - eliminates a large swath of target-dependent code >>>>> - allows for covering up the inability to declare >>>>> types with alignment > 64 bits >>>>> >>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 21:48:56 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:48:56 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: The same way as before. I think this operates at too low a level to get any automatic initialization. TryStmt.m3 and TryFinStmt.m3: ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); I agree though, this might not be ideal. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 15:42:33 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I don't understand what you mean by "initializes to NIL". > How are you creating the frame variable? > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > Ok. > > Do you know where to initialize the jmpbuf to NIL? > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > it checks for NIL and branches around the alloca for non-NIL, but it > > also initializes to NIL repeatedly, so no change effectively. > > > > > > Index: misc/Marker.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > retrieving revision 1.7 > > diff -u -w -r1.7 Marker.m3 > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > @@ -233,6 +233,7 @@ > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > VAR new: BOOLEAN; > > + label := CG.Next_label (); > > BEGIN > > (* int setjmp(void* ); *) > > IF (setjmp = NIL) THEN > > @@ -263,18 +264,25 @@ > > Target.Word.cg_type, 0); > > END; > > > > + (* IF frame.jmpbuf = NIL THEN *) > > + > > + CG.Load_nil (); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > + > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > CG.Pop_param (Target.Word.cg_type); > > CG.Call_direct (alloca, Target.Address.cg_type); > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > + (* END *) > > + CG.Set_label (label); > > > > (* setmp(frame.jmpbuf) *) > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > CG.Pop_param (CG.Type.Addr); > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > CG.If_true (handler, CG.Never); > > cvs diff: Diffing stmts > > Index: stmts/TryFinStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > retrieving revision 1.6 > > diff -u -w -r1.6 TryFinStmt.m3 > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -299,6 +299,10 @@ > > CG.Load_nil (); > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > l := CG.Next_label (3); > > CG.Set_label (l, barrier := TRUE); > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > Index: stmts/TryStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > retrieving revision 1.3 > > diff -u -w -r1.3 TryStmt.m3 > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -10,7 +10,7 @@ > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > TYPE > > @@ -411,6 +411,10 @@ > > CG.Store_addr (frame, M3RT.EF1_exception); > > ***********************************************) > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > IF (p.hasElse) THEN > > Marker.PushTryElse (l, l+1, frame); > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > Thanks, > > - Jay > > > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >> > >>> > >>> I believe you can, but it'd take significant work in the frontend. > >>> The jmpbuf should identify merely which procedure/frame to return to. > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>> Instead of setjmp, the compiler pessimizes appropriately. > >>> > >>> > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>> where in the function it is. > >>> > >>> > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>> > >>> > >>> It is more work through, granted, I can understand that. > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>> > >>> > >>> Anyway, I'm trying what you say, like for TRY within a loop. > >>> > >>> > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>> It aligns more. So it is using more stack than the other way. > >>> And it might pessimize codegen in other ways. > >>> > >>> > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>> function/frame to return to, and that within the frame there is a local integer to determine > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>> > >>> > >>> - Jay > >>> > >>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>> since they can be nested. > >>>> > >>>> > >>>> > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>> > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>> local "EF1" for each try. > >>>> I guess, really, it is EF1, EF2, etc. > >>>> So there should be a separate local for the jmpbuf pointer, and store > >>>> it in each EF* block? > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>> to in the front end, I need to read it more. > >>>> > >>>> something like: > >>>> > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>> END END END END F1; > >>>> => > >>>> > >>>> void F1() > >>>> { > >>>> jmp_buf* jb = 0; > >>>> EF1 a,b,c; > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>> do stuff 1... > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>> do stuff 2... > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>> do stuff 3... > >>>> } > >>>> > >>>> (The actual syntactic and semantic correctness of this code -- the > >>>> existance of the ternary operator, and that it only evaluates one side > >>>> or the other, and that assignment is expression..I quite like those > >>>> features....) > >>>> > >>>> > >>>> Still, something I can't pin down strikes me as too simple here. > >>>> > >>>> > >>>> If there is just one setjmp, and no integer(s) to keep track of > >>>> additional progress, you only ever know the last place you were in a > >>>> function. > >>>> That doesn't seem adequate. > >>>> > >>>> > >>>> What if a function raises an exception, catches it within itself, and > >>>> then raises something else, and then wants to catch that? > >>>> It won't know where to resume, right? It's just keep longjmping to the > >>>> same place. > >>>> > >>>> > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>> across functions. > >>>> I think somehow that is related here. > >>>> > >>>> > >>>> e.g. how would you ensure forward progress in this: > >>>> > >>>> > >>>> EXCEPTION E1; > >>>> EXCEPTION E2; > >>>> EXCEPTION E3; > >>>> > >>>> > >>>> PROCEDURE F4() RAISES ANY = > >>>> CONST Function = "F4 "; > >>>> BEGIN > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> RAISE E1; > >>>> EXCEPT ELSE > >>>> RAISE E2; > >>>> END; > >>>> EXCEPT ELSE > >>>> RAISE E3; > >>>> END; > >>>> EXCEPT ELSE > >>>> END; > >>>> END F4; > >>>> > >>>> > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> I am OK with what you have currently: > >>>> > >>>> At each TRY: > >>>> > >>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>> if the corresponding local variable is NIL. > >>>> 2. If not, then alloca and save its pointer in the local variable > >>>> 3. Execute the try block. > >>>> > >>>> As you say, alloca should turn into an inline operation using the > >>>> compiler's builtin implementation of alloca. > >>>> > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>> > >>>>> Code size will suffer. > >>>> > >>>> > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>> I thought it'd only be one call. I didn't realize our implementation > >>>> is as poor as it is, since a better but still > >>>> portable implementation doesn't seem too too difficult. > >>>> > >>>> > >>>> Can we maybe do the optimizations I indicate -- no more than one > >>>> setjmp/alloca/pushframe per function? > >>>> Using a local integer to record the position within the function? > >>>> > >>>> > >>>> Or just give me a week or few to get stack walking working and then > >>>> live the regression on other targets? > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>> possible; NT does have a decent runtime here..) > >>>> > >>>> > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>> > >>>> > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>> It doesn't work for intra-function jumps, only inter-function. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>> > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>> point is, you'd rather have n locals, which the backend automatically > >>>> merges, than n calls to alloca? > >>>> It's not a huge difference -- there are still going to be n calls to > >>>> setjmp and n calls to pthread_getspecific. > >>>> The alloca calls will be dwarfed. > >>>> Code size will suffer. > >>>> > >>>> > >>>> And, even so, there are plenty of optimizations to be had, even if > >>>> setjmp/pthread_getspecific is used. > >>>> > >>>> > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>> per function > >>>> - The calls to alloca could be merged. The frontend could keep track > >>>> of how many calls it makes per function, > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>> > >>>> > >>>> So, yes, given my current understanding, it is progress. > >>>> The target-dependence is not worth it, imho. > >>>> I'll still do some comparisons to release. > >>>> > >>>> > >>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>> > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>> I'll do more testing. > >>>> > >>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>> > >>>> > >>>> So the additional inefficiency is multiplied the same as the rest of > >>>> the preexisting inefficiency. > >>>> And the preexisting inefficiency is way more than the increase. > >>>> > >>>> And second, either way, it could be better. > >>>> > >>>> Basically, the model should be, that if a function has any try or lock, > >>>> it calls setjmp once. > >>>> And then, it should have one volatile integer, that in a sense > >>>> represents the line number. > >>>> But not really. It's like, every time you cross a TRY, the integer is > >>>> incremented, every time you > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>> value can be stored. > >>>> And then there is a maximum of one one handler per function, it > >>>> switches on the integer > >>>> to decide where it got into the function and what it should do. > >>>> > >>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Note that you need a different jmpbuf for each nested TRY! > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>> > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>> it -- check for NIL. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>> are allocating on every TRY where previously the storage was statically > >>>> allocated. Do you really think this is progress? > >>>> > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>> > >>>> I've back with full keyboard if more explanation needed. The diff is > >>>> actually fairly small to read. > >>>> I understand it is definitely less efficient, a few more instructions > >>>> for every try/lock. > >>>> No extra function call, at least with gcc backend. > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>> is written so that it should work > >>>> but I have to test it to be sure, will to roughly tonight. And there > >>>> probably is a function call there. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>> CC: m3commit at elegosoft.com > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>> definitely a bit less efficient, but the significant advantage is > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>> > >>>> > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>> the problem is addressed there. > >>>> > >>>> > >>>> The inefficiency of course can be dramatically mitigated via a stack > >>>> walker. I wanted to do this first though, while more targets using > >>>> setjmp. > >>>> > >>>> - Jay/phone > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Can you provide a more descriptive checkin comment? I don't know what > >>>> has been done here without diving into the diff. > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>> > >>>> diff attached > >>>> > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>> To: m3commit at elegosoft.com > >>>>> From: jkrell at elego.de > >>>>> Subject: [M3commit] CVS Update: cm3 > >>>>> > >>>>> CVSROOT: /usr/cvs > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>> > >>>>> Modified files: > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>> > >>>>> Log message: > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>> > >>>>> to allocate jmp_buf > >>>>> > >>>>> - eliminates a large swath of target-dependent code > >>>>> - allows for covering up the inability to declare > >>>>> types with alignment > 64 bits > >>>>> > >>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>> > >> > > > From jay.krell at cornell.edu Thu Jan 6 21:51:58 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:51:58 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: ps: I think there other non-ideal initializations here. e.g. TryFinStmt.m3:Compile2 ??? (* declare and initialize the info record *) ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_procedure (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_handler); ??? CG.Load_static_link (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_frame); Putting TRY/LOCK in loops probably repeatedly does the same initializations. Granted, this is non-stack-walker code. Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. ?- Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 20:48:56 +0000 > > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 15:42:33 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > I don't understand what you mean by "initializes to NIL". > > How are you creating the frame variable? > > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > > > > Ok. > > > Do you know where to initialize the jmpbuf to NIL? > > > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > > it checks for NIL and branches around the alloca for non-NIL, but it > > > also initializes to NIL repeatedly, so no change effectively. > > > > > > > > > Index: misc/Marker.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > > retrieving revision 1.7 > > > diff -u -w -r1.7 Marker.m3 > > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -233,6 +233,7 @@ > > > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > > VAR new: BOOLEAN; > > > + label := CG.Next_label (); > > > BEGIN > > > (* int setjmp(void* ); *) > > > IF (setjmp = NIL) THEN > > > @@ -263,18 +264,25 @@ > > > Target.Word.cg_type, 0); > > > END; > > > > > > + (* IF frame.jmpbuf = NIL THEN *) > > > + > > > + CG.Load_nil (); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > > + > > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > > CG.Pop_param (Target.Word.cg_type); > > > CG.Call_direct (alloca, Target.Address.cg_type); > > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > + (* END *) > > > + CG.Set_label (label); > > > > > > (* setmp(frame.jmpbuf) *) > > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > CG.Pop_param (CG.Type.Addr); > > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > > CG.If_true (handler, CG.Never); > > > cvs diff: Diffing stmts > > > Index: stmts/TryFinStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > > retrieving revision 1.6 > > > diff -u -w -r1.6 TryFinStmt.m3 > > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -299,6 +299,10 @@ > > > CG.Load_nil (); > > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > l := CG.Next_label (3); > > > CG.Set_label (l, barrier := TRUE); > > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > > Index: stmts/TryStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > > retrieving revision 1.3 > > > diff -u -w -r1.3 TryStmt.m3 > > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -10,7 +10,7 @@ > > > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > > > TYPE > > > @@ -411,6 +411,10 @@ > > > CG.Store_addr (frame, M3RT.EF1_exception); > > > ***********************************************) > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > IF (p.hasElse) THEN > > > Marker.PushTryElse (l, l+1, frame); > > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > > > Thanks, > > > - Jay > > > > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >> > > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >> 305 N. University Street | West Lafayette | IN 47907 | USA > > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >> > > >> > > >> > > >> > > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >> > > >>> > > >>> I believe you can, but it'd take significant work in the frontend. > > >>> The jmpbuf should identify merely which procedure/frame to return to. > > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>> Instead of setjmp, the compiler pessimizes appropriately. > > >>> > > >>> > > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>> where in the function it is. > > >>> > > >>> > > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>> > > >>> > > >>> It is more work through, granted, I can understand that. > > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>> > > >>> > > >>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>> > > >>> > > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>> It aligns more. So it is using more stack than the other way. > > >>> And it might pessimize codegen in other ways. > > >>> > > >>> > > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>> function/frame to return to, and that within the frame there is a local integer to determine > > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>> > > >>> > > >>> - Jay > > >>> > > >>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>> since they can be nested. > > >>>> > > >>>> > > >>>> > > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>> > > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>> local "EF1" for each try. > > >>>> I guess, really, it is EF1, EF2, etc. > > >>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>> it in each EF* block? > > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>> to in the front end, I need to read it more. > > >>>> > > >>>> something like: > > >>>> > > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>> END END END END F1; > > >>>> => > > >>>> > > >>>> void F1() > > >>>> { > > >>>> jmp_buf* jb = 0; > > >>>> EF1 a,b,c; > > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>> do stuff 1... > > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>> do stuff 2... > > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>> do stuff 3... > > >>>> } > > >>>> > > >>>> (The actual syntactic and semantic correctness of this code -- the > > >>>> existance of the ternary operator, and that it only evaluates one side > > >>>> or the other, and that assignment is expression..I quite like those > > >>>> features....) > > >>>> > > >>>> > > >>>> Still, something I can't pin down strikes me as too simple here. > > >>>> > > >>>> > > >>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>> additional progress, you only ever know the last place you were in a > > >>>> function. > > >>>> That doesn't seem adequate. > > >>>> > > >>>> > > >>>> What if a function raises an exception, catches it within itself, and > > >>>> then raises something else, and then wants to catch that? > > >>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>> same place. > > >>>> > > >>>> > > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>> across functions. > > >>>> I think somehow that is related here. > > >>>> > > >>>> > > >>>> e.g. how would you ensure forward progress in this: > > >>>> > > >>>> > > >>>> EXCEPTION E1; > > >>>> EXCEPTION E2; > > >>>> EXCEPTION E3; > > >>>> > > >>>> > > >>>> PROCEDURE F4() RAISES ANY = > > >>>> CONST Function = "F4 "; > > >>>> BEGIN > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> RAISE E1; > > >>>> EXCEPT ELSE > > >>>> RAISE E2; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> RAISE E3; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> END; > > >>>> END F4; > > >>>> > > >>>> > > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> I am OK with what you have currently: > > >>>> > > >>>> At each TRY: > > >>>> > > >>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>> if the corresponding local variable is NIL. > > >>>> 2. If not, then alloca and save its pointer in the local variable > > >>>> 3. Execute the try block. > > >>>> > > >>>> As you say, alloca should turn into an inline operation using the > > >>>> compiler's builtin implementation of alloca. > > >>>> > > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>> > > >>>>> Code size will suffer. > > >>>> > > >>>> > > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>> I thought it'd only be one call. I didn't realize our implementation > > >>>> is as poor as it is, since a better but still > > >>>> portable implementation doesn't seem too too difficult. > > >>>> > > >>>> > > >>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>> setjmp/alloca/pushframe per function? > > >>>> Using a local integer to record the position within the function? > > >>>> > > >>>> > > >>>> Or just give me a week or few to get stack walking working and then > > >>>> live the regression on other targets? > > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>> possible; NT does have a decent runtime here..) > > >>>> > > >>>> > > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>> > > >>>> > > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>> It doesn't work for intra-function jumps, only inter-function. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>> > > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>> point is, you'd rather have n locals, which the backend automatically > > >>>> merges, than n calls to alloca? > > >>>> It's not a huge difference -- there are still going to be n calls to > > >>>> setjmp and n calls to pthread_getspecific. > > >>>> The alloca calls will be dwarfed. > > >>>> Code size will suffer. > > >>>> > > >>>> > > >>>> And, even so, there are plenty of optimizations to be had, even if > > >>>> setjmp/pthread_getspecific is used. > > >>>> > > >>>> > > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>> per function > > >>>> - The calls to alloca could be merged. The frontend could keep track > > >>>> of how many calls it makes per function, > > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>> > > >>>> > > >>>> So, yes, given my current understanding, it is progress. > > >>>> The target-dependence is not worth it, imho. > > >>>> I'll still do some comparisons to release. > > >>>> > > >>>> > > >>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>> > > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>> I'll do more testing. > > >>>> > > >>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>> > > >>>> > > >>>> So the additional inefficiency is multiplied the same as the rest of > > >>>> the preexisting inefficiency. > > >>>> And the preexisting inefficiency is way more than the increase. > > >>>> > > >>>> And second, either way, it could be better. > > >>>> > > >>>> Basically, the model should be, that if a function has any try or lock, > > >>>> it calls setjmp once. > > >>>> And then, it should have one volatile integer, that in a sense > > >>>> represents the line number. > > >>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>> incremented, every time you > > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>> value can be stored. > > >>>> And then there is a maximum of one one handler per function, it > > >>>> switches on the integer > > >>>> to decide where it got into the function and what it should do. > > >>>> > > >>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Note that you need a different jmpbuf for each nested TRY! > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>> > > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>> it -- check for NIL. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>> are allocating on every TRY where previously the storage was statically > > >>>> allocated. Do you really think this is progress? > > >>>> > > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>> > > >>>> I've back with full keyboard if more explanation needed. The diff is > > >>>> actually fairly small to read. > > >>>> I understand it is definitely less efficient, a few more instructions > > >>>> for every try/lock. > > >>>> No extra function call, at least with gcc backend. > > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>> is written so that it should work > > >>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>> probably is a function call there. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> > > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>> definitely a bit less efficient, but the significant advantage is > > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>> > > >>>> > > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>> the problem is addressed there. > > >>>> > > >>>> > > >>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>> walker. I wanted to do this first though, while more targets using > > >>>> setjmp. > > >>>> > > >>>> - Jay/phone > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>> has been done here without diving into the diff. > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>> > > >>>> diff attached > > >>>> > > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>> To: m3commit at elegosoft.com > > >>>>> From: jkrell at elego.de > > >>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>> > > >>>>> CVSROOT: /usr/cvs > > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>> > > >>>>> Modified files: > > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>> > > >>>>> Log message: > > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>> > > >>>>> to allocate jmp_buf > > >>>>> > > >>>>> - eliminates a large swath of target-dependent code > > >>>>> - allows for covering up the inability to declare > > >>>>> types with alignment > 64 bits > > >>>>> > > >>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Thu Jan 6 21:58:54 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:58:54 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: What you want to do is use the "variable" slot in the frame to hold a variable for TRY frames, similarly to PROC frames. Then it will be initialized correctly. You should give it type Addr.T. On Jan 6, 2011, at 3:48 PM, Jay K wrote: > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 15:42:33 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I don't understand what you mean by "initializes to NIL". >> How are you creating the frame variable? >> If you do it properly the language semantics will cause it be initialized to NIL automatically. >> >> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >> >>> >>> Ok. >>> Do you know where to initialize the jmpbuf to NIL? >>> >>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>> it checks for NIL and branches around the alloca for non-NIL, but it >>> also initializes to NIL repeatedly, so no change effectively. >>> >>> >>> Index: misc/Marker.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>> retrieving revision 1.7 >>> diff -u -w -r1.7 Marker.m3 >>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -233,6 +233,7 @@ >>> >>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>> VAR new: BOOLEAN; >>> + label := CG.Next_label (); >>> BEGIN >>> (* int setjmp(void* ); *) >>> IF (setjmp = NIL) THEN >>> @@ -263,18 +264,25 @@ >>> Target.Word.cg_type, 0); >>> END; >>> >>> + (* IF frame.jmpbuf = NIL THEN *) >>> + >>> + CG.Load_nil (); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>> + >>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>> CG.Pop_param (Target.Word.cg_type); >>> CG.Call_direct (alloca, Target.Address.cg_type); >>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> + (* END *) >>> + CG.Set_label (label); >>> >>> (* setmp(frame.jmpbuf) *) >>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> CG.Pop_param (CG.Type.Addr); >>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>> CG.If_true (handler, CG.Never); >>> cvs diff: Diffing stmts >>> Index: stmts/TryFinStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>> retrieving revision 1.6 >>> diff -u -w -r1.6 TryFinStmt.m3 >>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -299,6 +299,10 @@ >>> CG.Load_nil (); >>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> l := CG.Next_label (3); >>> CG.Set_label (l, barrier := TRUE); >>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>> Index: stmts/TryStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>> retrieving revision 1.3 >>> diff -u -w -r1.3 TryStmt.m3 >>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -10,7 +10,7 @@ >>> >>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>> >>> TYPE >>> @@ -411,6 +411,10 @@ >>> CG.Store_addr (frame, M3RT.EF1_exception); >>> ***********************************************) >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> IF (p.hasElse) THEN >>> Marker.PushTryElse (l, l+1, frame); >>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>> >>> >>> The set_label before one of the PushEFrames could be moved down a bit, >>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>> >>> Thanks, >>> - Jay >>> >>> >>> ---------------------------------------- >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>> >>>>> >>>>> I believe you can, but it'd take significant work in the frontend. >>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>> >>>>> >>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>> where in the function it is. >>>>> >>>>> >>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>> >>>>> >>>>> It is more work through, granted, I can understand that. >>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>> >>>>> >>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>> >>>>> >>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>> It aligns more. So it is using more stack than the other way. >>>>> And it might pessimize codegen in other ways. >>>>> >>>>> >>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>> >>>>> >>>>> - Jay >>>>> >>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>> since they can be nested. >>>>>> >>>>>> >>>>>> >>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>> >>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>> local "EF1" for each try. >>>>>> I guess, really, it is EF1, EF2, etc. >>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>> it in each EF* block? >>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>> to in the front end, I need to read it more. >>>>>> >>>>>> something like: >>>>>> >>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>> END END END END F1; >>>>>> => >>>>>> >>>>>> void F1() >>>>>> { >>>>>> jmp_buf* jb = 0; >>>>>> EF1 a,b,c; >>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>> do stuff 1... >>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>> do stuff 2... >>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>> do stuff 3... >>>>>> } >>>>>> >>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>> or the other, and that assignment is expression..I quite like those >>>>>> features....) >>>>>> >>>>>> >>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>> >>>>>> >>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>> additional progress, you only ever know the last place you were in a >>>>>> function. >>>>>> That doesn't seem adequate. >>>>>> >>>>>> >>>>>> What if a function raises an exception, catches it within itself, and >>>>>> then raises something else, and then wants to catch that? >>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>> same place. >>>>>> >>>>>> >>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>> across functions. >>>>>> I think somehow that is related here. >>>>>> >>>>>> >>>>>> e.g. how would you ensure forward progress in this: >>>>>> >>>>>> >>>>>> EXCEPTION E1; >>>>>> EXCEPTION E2; >>>>>> EXCEPTION E3; >>>>>> >>>>>> >>>>>> PROCEDURE F4() RAISES ANY = >>>>>> CONST Function = "F4 "; >>>>>> BEGIN >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> RAISE E1; >>>>>> EXCEPT ELSE >>>>>> RAISE E2; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> RAISE E3; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> END; >>>>>> END F4; >>>>>> >>>>>> >>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> I am OK with what you have currently: >>>>>> >>>>>> At each TRY: >>>>>> >>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>> if the corresponding local variable is NIL. >>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>> 3. Execute the try block. >>>>>> >>>>>> As you say, alloca should turn into an inline operation using the >>>>>> compiler's builtin implementation of alloca. >>>>>> >>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>> >>>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>> is as poor as it is, since a better but still >>>>>> portable implementation doesn't seem too too difficult. >>>>>> >>>>>> >>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>> setjmp/alloca/pushframe per function? >>>>>> Using a local integer to record the position within the function? >>>>>> >>>>>> >>>>>> Or just give me a week or few to get stack walking working and then >>>>>> live the regression on other targets? >>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>> possible; NT does have a decent runtime here..) >>>>>> >>>>>> >>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>> >>>>>> >>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>> >>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>> merges, than n calls to alloca? >>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>> setjmp and n calls to pthread_getspecific. >>>>>> The alloca calls will be dwarfed. >>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>> setjmp/pthread_getspecific is used. >>>>>> >>>>>> >>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>> per function >>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>> of how many calls it makes per function, >>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>> >>>>>> >>>>>> So, yes, given my current understanding, it is progress. >>>>>> The target-dependence is not worth it, imho. >>>>>> I'll still do some comparisons to release. >>>>>> >>>>>> >>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>> >>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>> I'll do more testing. >>>>>> >>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>> >>>>>> >>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>> the preexisting inefficiency. >>>>>> And the preexisting inefficiency is way more than the increase. >>>>>> >>>>>> And second, either way, it could be better. >>>>>> >>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>> it calls setjmp once. >>>>>> And then, it should have one volatile integer, that in a sense >>>>>> represents the line number. >>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>> incremented, every time you >>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>> value can be stored. >>>>>> And then there is a maximum of one one handler per function, it >>>>>> switches on the integer >>>>>> to decide where it got into the function and what it should do. >>>>>> >>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>> >>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>> it -- check for NIL. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>> are allocating on every TRY where previously the storage was statically >>>>>> allocated. Do you really think this is progress? >>>>>> >>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>> >>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>> actually fairly small to read. >>>>>> I understand it is definitely less efficient, a few more instructions >>>>>> for every try/lock. >>>>>> No extra function call, at least with gcc backend. >>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>> is written so that it should work >>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>> probably is a function call there. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> >>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>> definitely a bit less efficient, but the significant advantage is >>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>> >>>>>> >>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>> the problem is addressed there. >>>>>> >>>>>> >>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>> walker. I wanted to do this first though, while more targets using >>>>>> setjmp. >>>>>> >>>>>> - Jay/phone >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>> has been done here without diving into the diff. >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>> >>>>>> diff attached >>>>>> >>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>> To: m3commit at elegosoft.com >>>>>>> From: jkrell at elego.de >>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> CVSROOT: /usr/cvs >>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>> >>>>>>> Modified files: >>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>> >>>>>>> Log message: >>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>> >>>>>>> to allocate jmp_buf >>>>>>> >>>>>>> - eliminates a large swath of target-dependent code >>>>>>> - allows for covering up the inability to declare >>>>>>> types with alignment > 64 bits >>>>>>> >>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> > From hosking at cs.purdue.edu Thu Jan 6 22:00:08 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:00:08 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: In the code below there are no initializations. On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > ps: I think there other non-ideal initializations here. > e.g. > > > TryFinStmt.m3:Compile2 > (* declare and initialize the info record *) > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_procedure (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_handler); > CG.Load_static_link (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_frame); > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > Granted, this is non-stack-walker code. > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > - Jay > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 20:48:56 +0000 >> >> >> The same way as before. I think this operates at too low a level to get any automatic initialization. >> >> TryStmt.m3 and TryFinStmt.m3: >> >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >> CG.Type.Struct, 0, in_memory := TRUE, >> up_level := FALSE, f := CG.Never); >> >> I agree though, this might not be ideal. >> >> - Jay >> >> >> ---------------------------------------- >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> I don't understand what you mean by "initializes to NIL". >>> How are you creating the frame variable? >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>> >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>> >>>> >>>> Ok. >>>> Do you know where to initialize the jmpbuf to NIL? >>>> >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>> also initializes to NIL repeatedly, so no change effectively. >>>> >>>> >>>> Index: misc/Marker.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>> retrieving revision 1.7 >>>> diff -u -w -r1.7 Marker.m3 >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -233,6 +233,7 @@ >>>> >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>> VAR new: BOOLEAN; >>>> + label := CG.Next_label (); >>>> BEGIN >>>> (* int setjmp(void* ); *) >>>> IF (setjmp = NIL) THEN >>>> @@ -263,18 +264,25 @@ >>>> Target.Word.cg_type, 0); >>>> END; >>>> >>>> + (* IF frame.jmpbuf = NIL THEN *) >>>> + >>>> + CG.Load_nil (); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>> + >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>> CG.Pop_param (Target.Word.cg_type); >>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> + (* END *) >>>> + CG.Set_label (label); >>>> >>>> (* setmp(frame.jmpbuf) *) >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> CG.Pop_param (CG.Type.Addr); >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>> CG.If_true (handler, CG.Never); >>>> cvs diff: Diffing stmts >>>> Index: stmts/TryFinStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>> retrieving revision 1.6 >>>> diff -u -w -r1.6 TryFinStmt.m3 >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -299,6 +299,10 @@ >>>> CG.Load_nil (); >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> l := CG.Next_label (3); >>>> CG.Set_label (l, barrier := TRUE); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>> Index: stmts/TryStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>> retrieving revision 1.3 >>>> diff -u -w -r1.3 TryStmt.m3 >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -10,7 +10,7 @@ >>>> >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>> >>>> TYPE >>>> @@ -411,6 +411,10 @@ >>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>> ***********************************************) >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> IF (p.hasElse) THEN >>>> Marker.PushTryElse (l, l+1, frame); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>> >>>> >>>> The set_label before one of the PushEFrames could be moved down a bit, >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>> >>>> Thanks, >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>> >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>> >>>>> >>>>> >>>>> >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>> >>>>>> >>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>> >>>>>> >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>> where in the function it is. >>>>>> >>>>>> >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>> >>>>>> >>>>>> It is more work through, granted, I can understand that. >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>> >>>>>> >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>> >>>>>> >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>> It aligns more. So it is using more stack than the other way. >>>>>> And it might pessimize codegen in other ways. >>>>>> >>>>>> >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>> since they can be nested. >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>> >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>> local "EF1" for each try. >>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>> it in each EF* block? >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>> to in the front end, I need to read it more. >>>>>>> >>>>>>> something like: >>>>>>> >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>> END END END END F1; >>>>>>> => >>>>>>> >>>>>>> void F1() >>>>>>> { >>>>>>> jmp_buf* jb = 0; >>>>>>> EF1 a,b,c; >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>> do stuff 1... >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>> do stuff 2... >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>> do stuff 3... >>>>>>> } >>>>>>> >>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>> features....) >>>>>>> >>>>>>> >>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>> >>>>>>> >>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>> additional progress, you only ever know the last place you were in a >>>>>>> function. >>>>>>> That doesn't seem adequate. >>>>>>> >>>>>>> >>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>> then raises something else, and then wants to catch that? >>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>> same place. >>>>>>> >>>>>>> >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>> across functions. >>>>>>> I think somehow that is related here. >>>>>>> >>>>>>> >>>>>>> e.g. how would you ensure forward progress in this: >>>>>>> >>>>>>> >>>>>>> EXCEPTION E1; >>>>>>> EXCEPTION E2; >>>>>>> EXCEPTION E3; >>>>>>> >>>>>>> >>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>> CONST Function = "F4 "; >>>>>>> BEGIN >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> RAISE E1; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E2; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E3; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> END; >>>>>>> END F4; >>>>>>> >>>>>>> >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> I am OK with what you have currently: >>>>>>> >>>>>>> At each TRY: >>>>>>> >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>> if the corresponding local variable is NIL. >>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>> 3. Execute the try block. >>>>>>> >>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>> compiler's builtin implementation of alloca. >>>>>>> >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>> >>>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>> is as poor as it is, since a better but still >>>>>>> portable implementation doesn't seem too too difficult. >>>>>>> >>>>>>> >>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>> setjmp/alloca/pushframe per function? >>>>>>> Using a local integer to record the position within the function? >>>>>>> >>>>>>> >>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>> live the regression on other targets? >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>> possible; NT does have a decent runtime here..) >>>>>>> >>>>>>> >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>> >>>>>>> >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>> >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>> merges, than n calls to alloca? >>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>> The alloca calls will be dwarfed. >>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>> setjmp/pthread_getspecific is used. >>>>>>> >>>>>>> >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>> per function >>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>> of how many calls it makes per function, >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>> >>>>>>> >>>>>>> So, yes, given my current understanding, it is progress. >>>>>>> The target-dependence is not worth it, imho. >>>>>>> I'll still do some comparisons to release. >>>>>>> >>>>>>> >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>> >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>> I'll do more testing. >>>>>>> >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>> >>>>>>> >>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>> the preexisting inefficiency. >>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>> >>>>>>> And second, either way, it could be better. >>>>>>> >>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>> it calls setjmp once. >>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>> represents the line number. >>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>> incremented, every time you >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>> value can be stored. >>>>>>> And then there is a maximum of one one handler per function, it >>>>>>> switches on the integer >>>>>>> to decide where it got into the function and what it should do. >>>>>>> >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>> >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>> it -- check for NIL. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>> allocated. Do you really think this is progress? >>>>>>> >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>> >>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>> actually fairly small to read. >>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>> for every try/lock. >>>>>>> No extra function call, at least with gcc backend. >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>> is written so that it should work >>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>> probably is a function call there. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>> >>>>>>> >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>> the problem is addressed there. >>>>>>> >>>>>>> >>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>> setjmp. >>>>>>> >>>>>>> - Jay/phone >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>> has been done here without diving into the diff. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>> >>>>>>> diff attached >>>>>>> >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>> To: m3commit at elegosoft.com >>>>>>>> From: jkrell at elego.de >>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>> >>>>>>>> CVSROOT: /usr/cvs >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>> >>>>>>>> Modified files: >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>> >>>>>>>> Log message: >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>> >>>>>>>> to allocate jmp_buf >>>>>>>> >>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>> - allows for covering up the inability to declare >>>>>>>> types with alignment > 64 bits >>>>>>>> >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 22:17:03 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 21:17:03 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:00:08 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > In the code below there are no initializations. > > On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > > > > ps: I think there other non-ideal initializations here. > > e.g. > > > > > > TryFinStmt.m3:Compile2 > > (* declare and initialize the info record *) > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_procedure (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_handler); > > CG.Load_static_link (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_frame); > > > > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > Granted, this is non-stack-walker code. > > > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > > > - Jay > > > > ---------------------------------------- > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >> > >> > >> The same way as before. I think this operates at too low a level to get any automatic initialization. > >> > >> TryStmt.m3 and TryFinStmt.m3: > >> > >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >> CG.Type.Struct, 0, in_memory := TRUE, > >> up_level := FALSE, f := CG.Never); > >> > >> I agree though, this might not be ideal. > >> > >> - Jay > >> > >> > >> ---------------------------------------- > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> I don't understand what you mean by "initializes to NIL". > >>> How are you creating the frame variable? > >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>> > >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>> > >>>> > >>>> Ok. > >>>> Do you know where to initialize the jmpbuf to NIL? > >>>> > >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>> also initializes to NIL repeatedly, so no change effectively. > >>>> > >>>> > >>>> Index: misc/Marker.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>> retrieving revision 1.7 > >>>> diff -u -w -r1.7 Marker.m3 > >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -233,6 +233,7 @@ > >>>> > >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>> VAR new: BOOLEAN; > >>>> + label := CG.Next_label (); > >>>> BEGIN > >>>> (* int setjmp(void* ); *) > >>>> IF (setjmp = NIL) THEN > >>>> @@ -263,18 +264,25 @@ > >>>> Target.Word.cg_type, 0); > >>>> END; > >>>> > >>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>> + > >>>> + CG.Load_nil (); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>> + > >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>> CG.Pop_param (Target.Word.cg_type); > >>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> + (* END *) > >>>> + CG.Set_label (label); > >>>> > >>>> (* setmp(frame.jmpbuf) *) > >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> CG.Pop_param (CG.Type.Addr); > >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>> CG.If_true (handler, CG.Never); > >>>> cvs diff: Diffing stmts > >>>> Index: stmts/TryFinStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>> retrieving revision 1.6 > >>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -299,6 +299,10 @@ > >>>> CG.Load_nil (); > >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> l := CG.Next_label (3); > >>>> CG.Set_label (l, barrier := TRUE); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>> Index: stmts/TryStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>> retrieving revision 1.3 > >>>> diff -u -w -r1.3 TryStmt.m3 > >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -10,7 +10,7 @@ > >>>> > >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>> > >>>> TYPE > >>>> @@ -411,6 +411,10 @@ > >>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>> ***********************************************) > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> IF (p.hasElse) THEN > >>>> Marker.PushTryElse (l, l+1, frame); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>> > >>>> > >>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>> > >>>> Thanks, > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>> > >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>> > >>>>>> > >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>> where in the function it is. > >>>>>> > >>>>>> > >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>> > >>>>>> > >>>>>> It is more work through, granted, I can understand that. > >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>> > >>>>>> > >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>> > >>>>>> > >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>> It aligns more. So it is using more stack than the other way. > >>>>>> And it might pessimize codegen in other ways. > >>>>>> > >>>>>> > >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>> > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>> since they can be nested. > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>> > >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>> local "EF1" for each try. > >>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>> it in each EF* block? > >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>> to in the front end, I need to read it more. > >>>>>>> > >>>>>>> something like: > >>>>>>> > >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>> END END END END F1; > >>>>>>> => > >>>>>>> > >>>>>>> void F1() > >>>>>>> { > >>>>>>> jmp_buf* jb = 0; > >>>>>>> EF1 a,b,c; > >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>> do stuff 1... > >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>> do stuff 2... > >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>> do stuff 3... > >>>>>>> } > >>>>>>> > >>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>> features....) > >>>>>>> > >>>>>>> > >>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>> > >>>>>>> > >>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>> function. > >>>>>>> That doesn't seem adequate. > >>>>>>> > >>>>>>> > >>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>> then raises something else, and then wants to catch that? > >>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>> same place. > >>>>>>> > >>>>>>> > >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>> across functions. > >>>>>>> I think somehow that is related here. > >>>>>>> > >>>>>>> > >>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>> > >>>>>>> > >>>>>>> EXCEPTION E1; > >>>>>>> EXCEPTION E2; > >>>>>>> EXCEPTION E3; > >>>>>>> > >>>>>>> > >>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>> CONST Function = "F4 "; > >>>>>>> BEGIN > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> RAISE E1; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E2; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E3; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> END; > >>>>>>> END F4; > >>>>>>> > >>>>>>> > >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> I am OK with what you have currently: > >>>>>>> > >>>>>>> At each TRY: > >>>>>>> > >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>> if the corresponding local variable is NIL. > >>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>> 3. Execute the try block. > >>>>>>> > >>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>> compiler's builtin implementation of alloca. > >>>>>>> > >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>> > >>>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>> is as poor as it is, since a better but still > >>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>> > >>>>>>> > >>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>> setjmp/alloca/pushframe per function? > >>>>>>> Using a local integer to record the position within the function? > >>>>>>> > >>>>>>> > >>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>> live the regression on other targets? > >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>> possible; NT does have a decent runtime here..) > >>>>>>> > >>>>>>> > >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>> > >>>>>>> > >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>> > >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>> merges, than n calls to alloca? > >>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>> The alloca calls will be dwarfed. > >>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>> setjmp/pthread_getspecific is used. > >>>>>>> > >>>>>>> > >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>> per function > >>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>> of how many calls it makes per function, > >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>> > >>>>>>> > >>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>> The target-dependence is not worth it, imho. > >>>>>>> I'll still do some comparisons to release. > >>>>>>> > >>>>>>> > >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>> > >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>> I'll do more testing. > >>>>>>> > >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>> > >>>>>>> > >>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>> the preexisting inefficiency. > >>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>> > >>>>>>> And second, either way, it could be better. > >>>>>>> > >>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>> it calls setjmp once. > >>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>> represents the line number. > >>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>> incremented, every time you > >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>> value can be stored. > >>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>> switches on the integer > >>>>>>> to decide where it got into the function and what it should do. > >>>>>>> > >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>> > >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>> it -- check for NIL. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>> allocated. Do you really think this is progress? > >>>>>>> > >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>> > >>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>> actually fairly small to read. > >>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>> for every try/lock. > >>>>>>> No extra function call, at least with gcc backend. > >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>> is written so that it should work > >>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>> probably is a function call there. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> > >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>> > >>>>>>> > >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>> the problem is addressed there. > >>>>>>> > >>>>>>> > >>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>> setjmp. > >>>>>>> > >>>>>>> - Jay/phone > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>> has been done here without diving into the diff. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>> > >>>>>>> diff attached > >>>>>>> > >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>> To: m3commit at elegosoft.com > >>>>>>>> From: jkrell at elego.de > >>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>> > >>>>>>>> CVSROOT: /usr/cvs > >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>> > >>>>>>>> Modified files: > >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>> > >>>>>>>> Log message: > >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>> > >>>>>>>> to allocate jmp_buf > >>>>>>>> > >>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>> - allows for covering up the inability to declare > >>>>>>>> types with alignment > 64 bits > >>>>>>>> > >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > From hosking at cs.purdue.edu Thu Jan 6 22:56:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:56:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> You are confusing code emitted in the body of the loop with dynamic executions of that code. CG calls are all compile-time generation of code. On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > - Jay > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 16:00:08 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> In the code below there are no initializations. >> >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >> >>> >>> ps: I think there other non-ideal initializations here. >>> e.g. >>> >>> >>> TryFinStmt.m3:Compile2 >>> (* declare and initialize the info record *) >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, >>> CG.Type.Struct, 0, in_memory := TRUE, >>> up_level := FALSE, f := CG.Never); >>> CG.Load_procedure (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_handler); >>> CG.Load_static_link (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_frame); >>> >>> >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. >>> Granted, this is non-stack-walker code. >>> >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. >>> >>> - Jay >>> >>> ---------------------------------------- >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>> >>>> >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. >>>> >>>> TryStmt.m3 and TryFinStmt.m3: >>>> >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >>>> CG.Type.Struct, 0, in_memory := TRUE, >>>> up_level := FALSE, f := CG.Never); >>>> >>>> I agree though, this might not be ideal. >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> I don't understand what you mean by "initializes to NIL". >>>>> How are you creating the frame variable? >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>>>> >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>> >>>>>> >>>>>> Ok. >>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>> >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>> >>>>>> >>>>>> Index: misc/Marker.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>> retrieving revision 1.7 >>>>>> diff -u -w -r1.7 Marker.m3 >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -233,6 +233,7 @@ >>>>>> >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>> VAR new: BOOLEAN; >>>>>> + label := CG.Next_label (); >>>>>> BEGIN >>>>>> (* int setjmp(void* ); *) >>>>>> IF (setjmp = NIL) THEN >>>>>> @@ -263,18 +264,25 @@ >>>>>> Target.Word.cg_type, 0); >>>>>> END; >>>>>> >>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>> + >>>>>> + CG.Load_nil (); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>>>> + >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> + (* END *) >>>>>> + CG.Set_label (label); >>>>>> >>>>>> (* setmp(frame.jmpbuf) *) >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> CG.Pop_param (CG.Type.Addr); >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>> CG.If_true (handler, CG.Never); >>>>>> cvs diff: Diffing stmts >>>>>> Index: stmts/TryFinStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>> retrieving revision 1.6 >>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -299,6 +299,10 @@ >>>>>> CG.Load_nil (); >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> l := CG.Next_label (3); >>>>>> CG.Set_label (l, barrier := TRUE); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>> Index: stmts/TryStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>> retrieving revision 1.3 >>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -10,7 +10,7 @@ >>>>>> >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>> >>>>>> TYPE >>>>>> @@ -411,6 +411,10 @@ >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>> ***********************************************) >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> IF (p.hasElse) THEN >>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>> >>>>>> >>>>>> The set_label before one of the PushEFrames could be moved down a bit, >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>>>> >>>>>> Thanks, >>>>>> - Jay >>>>>> >>>>>> >>>>>> ---------------------------------------- >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>> >>>>>>>> >>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>> >>>>>>>> >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>>>> where in the function it is. >>>>>>>> >>>>>>>> >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>> >>>>>>>> >>>>>>>> It is more work through, granted, I can understand that. >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>>>> >>>>>>>> >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>> >>>>>>>> >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>> And it might pessimize codegen in other ways. >>>>>>>> >>>>>>>> >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>>>> >>>>>>>> >>>>>>>> - Jay >>>>>>>> >>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>>>> since they can be nested. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>>>> local "EF1" for each try. >>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>>>> it in each EF* block? >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>>>> to in the front end, I need to read it more. >>>>>>>>> >>>>>>>>> something like: >>>>>>>>> >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>>>> END END END END F1; >>>>>>>>> => >>>>>>>>> >>>>>>>>> void F1() >>>>>>>>> { >>>>>>>>> jmp_buf* jb = 0; >>>>>>>>> EF1 a,b,c; >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>>>> do stuff 1... >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>>>> do stuff 2... >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>>>> do stuff 3... >>>>>>>>> } >>>>>>>>> >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>>>> features....) >>>>>>>>> >>>>>>>>> >>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>> >>>>>>>>> >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>> additional progress, you only ever know the last place you were in a >>>>>>>>> function. >>>>>>>>> That doesn't seem adequate. >>>>>>>>> >>>>>>>>> >>>>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>>>> same place. >>>>>>>>> >>>>>>>>> >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>>>> across functions. >>>>>>>>> I think somehow that is related here. >>>>>>>>> >>>>>>>>> >>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>> >>>>>>>>> >>>>>>>>> EXCEPTION E1; >>>>>>>>> EXCEPTION E2; >>>>>>>>> EXCEPTION E3; >>>>>>>>> >>>>>>>>> >>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>> CONST Function = "F4 "; >>>>>>>>> BEGIN >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> RAISE E1; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E2; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E3; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> END; >>>>>>>>> END F4; >>>>>>>>> >>>>>>>>> >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> I am OK with what you have currently: >>>>>>>>> >>>>>>>>> At each TRY: >>>>>>>>> >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>> 3. Execute the try block. >>>>>>>>> >>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>> >>>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>>>> is as poor as it is, since a better but still >>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>> >>>>>>>>> >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>> >>>>>>>>> >>>>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>>>> live the regression on other targets? >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>> >>>>>>>>> >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>>>> >>>>>>>>> >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>> >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>>>> merges, than n calls to alloca? >>>>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>> >>>>>>>>> >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>>>> per function >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>>>> of how many calls it makes per function, >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>> >>>>>>>>> >>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>> I'll still do some comparisons to release. >>>>>>>>> >>>>>>>>> >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>> I'll do more testing. >>>>>>>>> >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>> >>>>>>>>> >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>>>> the preexisting inefficiency. >>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>> >>>>>>>>> And second, either way, it could be better. >>>>>>>>> >>>>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>>>> it calls setjmp once. >>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>> represents the line number. >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>>>> incremented, every time you >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>>>> value can be stored. >>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>> switches on the integer >>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>> >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>>>> it -- check for NIL. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>>>> actually fairly small to read. >>>>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>>>> for every try/lock. >>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>>>> is written so that it should work >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>>>> probably is a function call there. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>>>> >>>>>>>>> >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>>>> the problem is addressed there. >>>>>>>>> >>>>>>>>> >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>>>> setjmp. >>>>>>>>> >>>>>>>>> - Jay/phone >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>>>> has been done here without diving into the diff. >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> diff attached >>>>>>>>> >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>> From: jkrell at elego.de >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>> >>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>> >>>>>>>>>> Modified files: >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>> >>>>>>>>>> Log message: >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>> >>>>>>>>>> to allocate jmp_buf >>>>>>>>>> >>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>> types with alignment > 64 bits >>>>>>>>>> >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 05:08:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 04:08:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: I don't think so, but maybe. For i := 1 to 10 do try finally end will run that generated code 10 times but only the 1st is needed. In general? I not sure. Jay/phone > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:56:48 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > CG calls are all compile-time generation of code. > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > - Jay > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> In the code below there are no initializations. > >> > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >> > >>> > >>> ps: I think there other non-ideal initializations here. > >>> e.g. > >>> > >>> > >>> TryFinStmt.m3:Compile2 > >>> (* declare and initialize the info record *) > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > >>> CG.Type.Struct, 0, in_memory := TRUE, > >>> up_level := FALSE, f := CG.Never); > >>> CG.Load_procedure (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_handler); > >>> CG.Load_static_link (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_frame); > >>> > >>> > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > >>> Granted, this is non-stack-walker code. > >>> > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > >>> > >>> - Jay > >>> > >>> ---------------------------------------- > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>> > >>>> > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > >>>> > >>>> TryStmt.m3 and TryFinStmt.m3: > >>>> > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>> up_level := FALSE, f := CG.Never); > >>>> > >>>> I agree though, this might not be ideal. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> I don't understand what you mean by "initializes to NIL". > >>>>> How are you creating the frame variable? > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>>>> > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> Ok. > >>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>> > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>> > >>>>>> > >>>>>> Index: misc/Marker.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>> retrieving revision 1.7 > >>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -233,6 +233,7 @@ > >>>>>> > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>> VAR new: BOOLEAN; > >>>>>> + label := CG.Next_label (); > >>>>>> BEGIN > >>>>>> (* int setjmp(void* ); *) > >>>>>> IF (setjmp = NIL) THEN > >>>>>> @@ -263,18 +264,25 @@ > >>>>>> Target.Word.cg_type, 0); > >>>>>> END; > >>>>>> > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>> + > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>>>> + > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> + (* END *) > >>>>>> + CG.Set_label (label); > >>>>>> > >>>>>> (* setmp(frame.jmpbuf) *) > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>> CG.If_true (handler, CG.Never); > >>>>>> cvs diff: Diffing stmts > >>>>>> Index: stmts/TryFinStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>> retrieving revision 1.6 > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -299,6 +299,10 @@ > >>>>>> CG.Load_nil (); > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> l := CG.Next_label (3); > >>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>> Index: stmts/TryStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>> retrieving revision 1.3 > >>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -10,7 +10,7 @@ > >>>>>> > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>> > >>>>>> TYPE > >>>>>> @@ -411,6 +411,10 @@ > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>> ***********************************************) > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> IF (p.hasElse) THEN > >>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>> > >>>>>> > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>>>> > >>>>>> Thanks, > >>>>>> - Jay > >>>>>> > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>> > >>>>>>>> > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>> > >>>>>>>> > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>>>> where in the function it is. > >>>>>>>> > >>>>>>>> > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>> > >>>>>>>> > >>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>>>> > >>>>>>>> > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>> > >>>>>>>> > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>> > >>>>>>>> > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>>>> > >>>>>>>> > >>>>>>>> - Jay > >>>>>>>> > >>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>>>> since they can be nested. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>>>> local "EF1" for each try. > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>>>> it in each EF* block? > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>> > >>>>>>>>> something like: > >>>>>>>>> > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>>>> END END END END F1; > >>>>>>>>> => > >>>>>>>>> > >>>>>>>>> void F1() > >>>>>>>>> { > >>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>> EF1 a,b,c; > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>>>> do stuff 1... > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>>>> do stuff 2... > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>>>> do stuff 3... > >>>>>>>>> } > >>>>>>>>> > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>>>> features....) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>>>> function. > >>>>>>>>> That doesn't seem adequate. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>>>> same place. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>>>> across functions. > >>>>>>>>> I think somehow that is related here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> EXCEPTION E1; > >>>>>>>>> EXCEPTION E2; > >>>>>>>>> EXCEPTION E3; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>> CONST Function = "F4 "; > >>>>>>>>> BEGIN > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> RAISE E1; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E2; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E3; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> END; > >>>>>>>>> END F4; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> I am OK with what you have currently: > >>>>>>>>> > >>>>>>>>> At each TRY: > >>>>>>>>> > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>> 3. Execute the try block. > >>>>>>>>> > >>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>>>> live the regression on other targets? > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>> > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>>>> merges, than n calls to alloca? > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>>>> per function > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>>>> of how many calls it makes per function, > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>> I'll do more testing. > >>>>>>>>> > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>>>> the preexisting inefficiency. > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>> > >>>>>>>>> And second, either way, it could be better. > >>>>>>>>> > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>>>> it calls setjmp once. > >>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>> represents the line number. > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>>>> incremented, every time you > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>>>> value can be stored. > >>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>> switches on the integer > >>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>> > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>>>> it -- check for NIL. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>>>> actually fairly small to read. > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>>>> for every try/lock. > >>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>>>> is written so that it should work > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>>>> probably is a function call there. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>>>> the problem is addressed there. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>>>> setjmp. > >>>>>>>>> > >>>>>>>>> - Jay/phone > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>>>> has been done here without diving into the diff. > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> diff attached > >>>>>>>>> > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>> > >>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>> > >>>>>>>>>> Modified files: > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>> > >>>>>>>>>> Log message: > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>> > >>>>>>>>>> to allocate jmp_buf > >>>>>>>>>> > >>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>> > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 7 05:24:31 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 23:24:31 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Ah, yes, I see. You're right. The same proc is stored multiple times. We could indeed simply have a variable initialized once with the value of the proc. On Jan 6, 2011, at 11:08 PM, Jay K wrote: > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>>>>>>> are allocating on every TRY where previously the storage was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 7 06:38:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 05:38:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Now, for all I know it is loading from a variable and the variable can change. That's my uncertainty. There is other similar code that I'm even less certain of, specifically: MODULE TryStmt; PROCEDURE Compile1 (p: P): Stmt.Outcomes = ??? (* declare and initialize the info record *) ??? info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, ????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_nil (); ??? CG.Store_addr (info, M3RT.EA_exception); It could very well be that in: ?For i := 1 to 10 do try ... may or may not throw ... except else info needs to be nulled each time through. If you fixup this stuff, I'll know more easily how to remove the allocas from loops. Or maybe I can figure it out anyway from your clue. (Or maybe I'll first go after Mika's two failing pieces of code..) Thanks, ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 23:24:31 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I see. You're right. > The same proc is stored multiple times. > We could indeed simply have a variable initialized once with the value > of the proc. > > > On Jan 6, 2011, at 11:08 PM, Jay K wrote: > > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In > general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic > executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going > to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same > initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of > m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level > to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be > initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved > down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, > but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp > implementation to one that relies on unwind support, so I don't think > the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to > return to. > > >>>>>>>> There would also be a volatile local integer, that gets > altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that > integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a > highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is > reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or > one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the > volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current > Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many > platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. > the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables > merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there > is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per > TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code > allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, > and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code > -- the > > >>>>>>>>> existance of the ternary operator, and that it only > evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite > like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you > were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within > itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep > longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global > unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated > by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our > implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working > and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about > jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend > automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n > calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, > even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to > setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could > keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder > relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already > worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for > each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as > the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any > try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the > integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or > rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple > sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more > testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > But now you > > >>>>>>>>> are allocating on every TRY where previously the storage > was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. > The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more > instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. > And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: > the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a > jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf > aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated > via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more > targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> > CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't > know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety > slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least > with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Fri Jan 7 08:25:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 7 Jan 2011 02:25:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > Now, for all I know it is loading from a variable and the variable can change. > That's my uncertainty. > > > There is other similar code that I'm even less certain of, specifically: > > MODULE TryStmt; > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > (* declare and initialize the info record *) > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_nil (); > CG.Store_addr (info, M3RT.EA_exception); > > It could very well be that in: > > For i := 1 to 10 do try ... may or may not throw ... except else > > info needs to be nulled each time through. > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > Or maybe I can figure it out anyway from your clue. > (Or maybe I'll first go after Mika's two failing pieces of code..) > > Thanks, > - Jay > > > > > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 23:24:31 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I see. You're right. >> The same proc is stored multiple times. >> We could indeed simply have a variable initialized once with the value >> of the proc. >> >> >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: >> >> I don't think so, but maybe. >> >> For i := 1 to 10 do try finally end >> >> will run that generated code 10 times but only the 1st is needed. In >> general? I not sure. >> >> Jay/phone >> >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> You are confusing code emitted in the body of the loop with dynamic >> executions of that code. >>> CG calls are all compile-time generation of code. >>> >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: >>> >>>> >>>> If I have a try/finally or lock in a loop, those lines aren't going >> to guaranteeably store the same values each time? >>>> >>>> - Jay >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> In the code below there are no initializations. >>>>> >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >>>>> >>>>>> >>>>>> ps: I think there other non-ideal initializations here. >>>>>> e.g. >>>>>> >>>>>> >>>>>> TryFinStmt.m3:Compile2 >>>>>> (* declare and initialize the info record *) >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, >> Target.Address.align, >>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>> up_level := FALSE, f := CG.Never); >>>>>> CG.Load_procedure (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); >>>>>> CG.Load_static_link (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); >>>>>> >>>>>> >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same >> initializations. >>>>>> Granted, this is non-stack-walker code. >>>>>> >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of >> m3front still.. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ---------------------------------------- >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>>>>> >>>>>>> >>>>>>> The same way as before. I think this operates at too low a level >> to get any automatic initialization. >>>>>>> >>>>>>> TryStmt.m3 and TryFinStmt.m3: >>>>>>> >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, >> Target.Address.align, >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>>> up_level := FALSE, f := CG.Never); >>>>>>> >>>>>>> I agree though, this might not be ideal. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ---------------------------------------- >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>> From: hosking at cs.purdue.edu >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>>>>> CC: m3commit at elegosoft.com >>>>>>>> To: jay.krell at cornell.edu >>>>>>>> >>>>>>>> I don't understand what you mean by "initializes to NIL". >>>>>>>> How are you creating the frame variable? >>>>>>>> If you do it properly the language semantics will cause it be >> initialized to NIL automatically. >>>>>>>> >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> Ok. >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>>>>> >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* >> to correct, >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>>>>> >>>>>>>>> >>>>>>>>> Index: misc/Marker.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>>>>> retrieving revision 1.7 >>>>>>>>> diff -u -w -r1.7 Marker.m3 >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -233,6 +233,7 @@ >>>>>>>>> >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>>>>> VAR new: BOOLEAN; >>>>>>>>> + label := CG.Next_label (); >>>>>>>>> BEGIN >>>>>>>>> (* int setjmp(void* ); *) >>>>>>>>> IF (setjmp = NIL) THEN >>>>>>>>> @@ -263,18 +264,25 @@ >>>>>>>>> Target.Word.cg_type, 0); >>>>>>>>> END; >>>>>>>>> >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>>>>> + >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, >> CG.Maybe); >>>>>>>>> + >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> + (* END *) >>>>>>>>> + CG.Set_label (label); >>>>>>>>> >>>>>>>>> (* setmp(frame.jmpbuf) *) >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> CG.Pop_param (CG.Type.Addr); >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>>>>> CG.If_true (handler, CG.Never); >>>>>>>>> cvs diff: Diffing stmts >>>>>>>>> Index: stmts/TryFinStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>>>>> retrieving revision 1.6 >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -299,6 +299,10 @@ >>>>>>>>> CG.Load_nil (); >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> l := CG.Next_label (3); >>>>>>>>> CG.Set_label (l, barrier := TRUE); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>>>>> Index: stmts/TryStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>>>>> retrieving revision 1.3 >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -10,7 +10,7 @@ >>>>>>>>> >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, >> Error, Marker; >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>>>>> >>>>>>>>> TYPE >>>>>>>>> @@ -411,6 +411,10 @@ >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>>>>> ***********************************************) >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> IF (p.hasElse) THEN >>>>>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>>>>> >>>>>>>>> >>>>>>>>> The set_label before one of the PushEFrames could be moved >> down a bit, >>>>>>>>> to after the NIL initialization, and that'd fix some cases, >> but I think not all. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ---------------------------------------- >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>> >>>>>>>>>> At this point, we are trying to move away from the setjmp >> implementation to one that relies on unwind support, so I don't think >> the effort here is worthwhile. >>>>>>>>>> >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to >> return to. >>>>>>>>>>> There would also be a volatile local integer, that gets >> altered at certain points through the function. >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that >> integer to determine where to "really" go. >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a >> highly optimized frame based exception >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is >> reserved to be the head of the linked list of frames. >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> So the result is that a function with one or more tries, or >> one or more locals with destructors, >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the >> volatile local integer to indicate >>>>>>>>>>> where in the function it is. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> If NT/x86 were inefficient more analogous to current >> Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> It is more work through, granted, I can understand that. >>>>>>>>>>> And given that we have a much better option for many >> platforms, the payoff would be reduced. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. >> the previous approach. >>>>>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>>>>> And it might pessimize codegen in other ways. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables >> merely describe, again, which >>>>>>>>>>> function/frame to return to, and that within the frame there >> is a local integer to determine >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a >> switch. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> - Jay >>>>>>>>>>> >>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per >> TRY scope, >>>>>>>>>>>> since they can be nested. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code >> allocates a >>>>>>>>>>>> local "EF1" for each try. >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, >> and store >>>>>>>>>>>> it in each EF* block? >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily >> figure out how >>>>>>>>>>>> to in the front end, I need to read it more. >>>>>>>>>>>> >>>>>>>>>>>> something like: >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 >> do stuff 3 >>>>>>>>>>>> END END END END F1; >>>>>>>>>>>> => >>>>>>>>>>>> >>>>>>>>>>>> void F1() >>>>>>>>>>>> { >>>>>>>>>>>> jmp_buf* jb = 0; >>>>>>>>>>>> EF1 a,b,c; >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY1 >>>>>>>>>>>> do stuff 1... >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY2 >>>>>>>>>>>> do stuff 2... >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY3 >>>>>>>>>>>> do stuff 3... >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code >> -- the >>>>>>>>>>>> existance of the ternary operator, and that it only >> evaluates one side >>>>>>>>>>>> or the other, and that assignment is expression..I quite >> like those >>>>>>>>>>>> features....) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>>>>> additional progress, you only ever know the last place you >> were in a >>>>>>>>>>>> function. >>>>>>>>>>>> That doesn't seem adequate. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> What if a function raises an exception, catches it within >> itself, and >>>>>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>>>>> It won't know where to resume, right? It's just keep >> longjmping to the >>>>>>>>>>>> same place. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and >> "global unwind". >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global >> unwind" is >>>>>>>>>>>> across functions. >>>>>>>>>>>> I think somehow that is related here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> EXCEPTION E1; >>>>>>>>>>>> EXCEPTION E2; >>>>>>>>>>>> EXCEPTION E3; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>>>>> CONST Function = "F4 "; >>>>>>>>>>>> BEGIN >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> RAISE E1; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E2; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E3; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> END; >>>>>>>>>>>> END F4; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> I am OK with what you have currently: >>>>>>>>>>>> >>>>>>>>>>>> At each TRY: >>>>>>>>>>>> >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated >> by checking >>>>>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>>>>> 3. Execute the try block. >>>>>>>>>>>> >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in >> functions that use try. >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n >> calls for n trys. >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our >> implementation >>>>>>>>>>>> is as poor as it is, since a better but still >>>>>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Or just give me a week or few to get stack walking working >> and then >>>>>>>>>>>> live the regression on other targets? >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* >> certainly >>>>>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> It *is* nice to not have have the frontend know about >> jmpbuf size. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be >> used so easily. >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>>>>> >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I >> guess your >>>>>>>>>>>> point is, you'd rather have n locals, which the backend >> automatically >>>>>>>>>>>> merges, than n calls to alloca? >>>>>>>>>>>> It's not a huge difference -- there are still going to be n >> calls to >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, >> even if >>>>>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - It could make a maximum of one call to >> setjmp/pthread_getspecific >>>>>>>>>>>> per function >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could >> keep track >>>>>>>>>>>> of how many calls it makes per function, >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>>>>> I'll still do some comparisons to release. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I'll still be looking into using the gcc unwinder >> relatively soon. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already >> worked maybe? >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>>>>> I'll do more testing. >>>>>>>>>>>> >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for >> each TRY >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So the additional inefficiency is multiplied the same as >> the rest of >>>>>>>>>>>> the preexisting inefficiency. >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>>>>> >>>>>>>>>>>> And second, either way, it could be better. >>>>>>>>>>>> >>>>>>>>>>>> Basically, the model should be, that if a function has any >> try or lock, >>>>>>>>>>>> it calls setjmp once. >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>>>>> represents the line number. >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the >> integer is >>>>>>>>>>>> incremented, every time you >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or >> rather, the >>>>>>>>>>>> value can be stored. >>>>>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>>>>> switches on the integer >>>>>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>>>>> >>>>>>>>>>>> This is how other compilers work and it is a fairly simple >> sensible approach. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more >> testing and fix >>>>>>>>>>>> it -- check for NIL. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. >> But now you >>>>>>>>>>>> are allocating on every TRY where previously the storage >> was statically >>>>>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> I've back with full keyboard if more explanation needed. >> The diff is >>>>>>>>>>>> actually fairly small to read. >>>>>>>>>>>> I understand it is definitely less efficient, a few more >> instructions >>>>>>>>>>>> for every try/lock. >>>>>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- >> the change >>>>>>>>>>>> is written so that it should work >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. >> And there >>>>>>>>>>>> probably is a function call there. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: >> the jumpbuf in >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a >> jumpbuf. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf >> aligned to >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and >> alloca seems >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine >> currently to see if >>>>>>>>>>>> the problem is addressed there. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated >> via a stack >>>>>>>>>>>> walker. I wanted to do this first though, while more >> targets using >>>>>>>>>>>> setjmp. >>>>>>>>>>>> >>>>>>>>>>>> - Jay/phone >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>>>>> >> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't >> know what >>>>>>>>>>>> has been done here without diving into the diff. >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> diff attached >>>>>>>>>>>> >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>>>>> From: jkrell at elego.de >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>>>>> >>>>>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>>>>> >>>>>>>>>>>>> Modified files: >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>>>>> >>>>>>>>>>>>> Log message: >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>>>>> >>>>>>>>>>>>> to allocate jmp_buf >>>>>>>>>>>>> >>>>>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>>>>> types with alignment > 64 bits >>>>>>>>>>>>> >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety >> slow path. >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least >> with gcc backend. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 11:46:05 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 10:46:05 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> , Message-ID: > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. Correct. That part is easy to code and I have correct on my machine. What I don't have is doing the initialization, early enough in the generated code to be just once. ?> Perhaps that is not so easy, because you need to declare the variable in the outermost scope. Right. And still one per try. The current code is pretty bad, for try within a loop. I should also point out that the alloca approach is using a fair amount more stack. ?- the alloca is rounded up a lot for alignment ?- the extra pointer; but mainly I think the alignment Agreed, what I want to fix is more significant than the other "problem" I brought up, since one is allocating more and more stack, the other is not. One "problem" I just introduced, hasn't been around any amount of time, the other is long standing and nobody noticed. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Fri, 7 Jan 2011 02:25:30 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? > > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. > My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. > > On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > > > > Now, for all I know it is loading from a variable and the variable can change. > > That's my uncertainty. > > > > > > There is other similar code that I'm even less certain of, specifically: > > > > MODULE TryStmt; > > > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > > > (* declare and initialize the info record *) > > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_nil (); > > CG.Store_addr (info, M3RT.EA_exception); > > > > It could very well be that in: > > > > For i := 1 to 10 do try ... may or may not throw ... except else > > > > info needs to be nulled each time through. > > > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > > Or maybe I can figure it out anyway from your clue. > > (Or maybe I'll first go after Mika's two failing pieces of code..) > > > > Thanks, > > - Jay > > > > > > > > > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 23:24:31 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I see. You're right. > >> The same proc is stored multiple times. > >> We could indeed simply have a variable initialized once with the value > >> of the proc. > >> > >> > >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: > >> > >> I don't think so, but maybe. > >> > >> For i := 1 to 10 do try finally end > >> > >> will run that generated code 10 times but only the 1st is needed. In > >> general? I not sure. > >> > >> Jay/phone > >> > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> You are confusing code emitted in the body of the loop with dynamic > >> executions of that code. > >>> CG calls are all compile-time generation of code. > >>> > >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: > >>> > >>>> > >>>> If I have a try/finally or lock in a loop, those lines aren't going > >> to guaranteeably store the same values each time? > >>>> > >>>> - Jay > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> In the code below there are no initializations. > >>>>> > >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> ps: I think there other non-ideal initializations here. > >>>>>> e.g. > >>>>>> > >>>>>> > >>>>>> TryFinStmt.m3:Compile2 > >>>>>> (* declare and initialize the info record *) > >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > >> Target.Address.align, > >>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>> up_level := FALSE, f := CG.Never); > >>>>>> CG.Load_procedure (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); > >>>>>> CG.Load_static_link (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); > >>>>>> > >>>>>> > >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same > >> initializations. > >>>>>> Granted, this is non-stack-walker code. > >>>>>> > >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of > >> m3front still.. > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>>>>> > >>>>>>> > >>>>>>> The same way as before. I think this operates at too low a level > >> to get any automatic initialization. > >>>>>>> > >>>>>>> TryStmt.m3 and TryFinStmt.m3: > >>>>>>> > >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > >> Target.Address.align, > >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>>> up_level := FALSE, f := CG.Never); > >>>>>>> > >>>>>>> I agree though, this might not be ideal. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ---------------------------------------- > >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>> To: jay.krell at cornell.edu > >>>>>>>> > >>>>>>>> I don't understand what you mean by "initializes to NIL". > >>>>>>>> How are you creating the frame variable? > >>>>>>>> If you do it properly the language semantics will cause it be > >> initialized to NIL automatically. > >>>>>>>> > >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>>>>> > >>>>>>>>> > >>>>>>>>> Ok. > >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>>>>> > >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > >> to correct, > >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Index: misc/Marker.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>>>>> retrieving revision 1.7 > >>>>>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -233,6 +233,7 @@ > >>>>>>>>> > >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>>>>> VAR new: BOOLEAN; > >>>>>>>>> + label := CG.Next_label (); > >>>>>>>>> BEGIN > >>>>>>>>> (* int setjmp(void* ); *) > >>>>>>>>> IF (setjmp = NIL) THEN > >>>>>>>>> @@ -263,18 +264,25 @@ > >>>>>>>>> Target.Word.cg_type, 0); > >>>>>>>>> END; > >>>>>>>>> > >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>>>>> + > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > >> CG.Maybe); > >>>>>>>>> + > >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> + (* END *) > >>>>>>>>> + CG.Set_label (label); > >>>>>>>>> > >>>>>>>>> (* setmp(frame.jmpbuf) *) > >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>>>>> CG.If_true (handler, CG.Never); > >>>>>>>>> cvs diff: Diffing stmts > >>>>>>>>> Index: stmts/TryFinStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>>>>> retrieving revision 1.6 > >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -299,6 +299,10 @@ > >>>>>>>>> CG.Load_nil (); > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> l := CG.Next_label (3); > >>>>>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>>>>> Index: stmts/TryStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>>>>> retrieving revision 1.3 > >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -10,7 +10,7 @@ > >>>>>>>>> > >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > >> Error, Marker; > >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>>>>> > >>>>>>>>> TYPE > >>>>>>>>> @@ -411,6 +411,10 @@ > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>>>>> ***********************************************) > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> IF (p.hasElse) THEN > >>>>>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The set_label before one of the PushEFrames could be moved > >> down a bit, > >>>>>>>>> to after the NIL initialization, and that'd fix some cases, > >> but I think not all. > >>>>>>>>> > >>>>>>>>> Thanks, > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ---------------------------------------- > >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>> > >>>>>>>>>> At this point, we are trying to move away from the setjmp > >> implementation to one that relies on unwind support, so I don't think > >> the effort here is worthwhile. > >>>>>>>>>> > >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to > >> return to. > >>>>>>>>>>> There would also be a volatile local integer, that gets > >> altered at certain points through the function. > >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that > >> integer to determine where to "really" go. > >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a > >> highly optimized frame based exception > >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is > >> reserved to be the head of the linked list of frames. > >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> So the result is that a function with one or more tries, or > >> one or more locals with destructors, > >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the > >> volatile local integer to indicate > >>>>>>>>>>> where in the function it is. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> If NT/x86 were inefficient more analogous to current > >> Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>>>>> And given that we have a much better option for many > >> platforms, the payoff would be reduced. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. > >> the previous approach. > >>>>>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables > >> merely describe, again, which > >>>>>>>>>>> function/frame to return to, and that within the frame there > >> is a local integer to determine > >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > >> switch. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> - Jay > >>>>>>>>>>> > >>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per > >> TRY scope, > >>>>>>>>>>>> since they can be nested. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code > >> allocates a > >>>>>>>>>>>> local "EF1" for each try. > >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, > >> and store > >>>>>>>>>>>> it in each EF* block? > >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > >> figure out how > >>>>>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>>>>> > >>>>>>>>>>>> something like: > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > >> do stuff 3 > >>>>>>>>>>>> END END END END F1; > >>>>>>>>>>>> => > >>>>>>>>>>>> > >>>>>>>>>>>> void F1() > >>>>>>>>>>>> { > >>>>>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>>>>> EF1 a,b,c; > >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY1 > >>>>>>>>>>>> do stuff 1... > >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY2 > >>>>>>>>>>>> do stuff 2... > >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY3 > >>>>>>>>>>>> do stuff 3... > >>>>>>>>>>>> } > >>>>>>>>>>>> > >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code > >> -- the > >>>>>>>>>>>> existance of the ternary operator, and that it only > >> evaluates one side > >>>>>>>>>>>> or the other, and that assignment is expression..I quite > >> like those > >>>>>>>>>>>> features....) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>>>>> additional progress, you only ever know the last place you > >> were in a > >>>>>>>>>>>> function. > >>>>>>>>>>>> That doesn't seem adequate. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> What if a function raises an exception, catches it within > >> itself, and > >>>>>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>>>>> It won't know where to resume, right? It's just keep > >> longjmping to the > >>>>>>>>>>>> same place. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > >> "global unwind". > >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global > >> unwind" is > >>>>>>>>>>>> across functions. > >>>>>>>>>>>> I think somehow that is related here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> EXCEPTION E1; > >>>>>>>>>>>> EXCEPTION E2; > >>>>>>>>>>>> EXCEPTION E3; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>>>>> CONST Function = "F4 "; > >>>>>>>>>>>> BEGIN > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> RAISE E1; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E2; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E3; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> END; > >>>>>>>>>>>> END F4; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> I am OK with what you have currently: > >>>>>>>>>>>> > >>>>>>>>>>>> At each TRY: > >>>>>>>>>>>> > >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated > >> by checking > >>>>>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>>>>> 3. Execute the try block. > >>>>>>>>>>>> > >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > >> functions that use try. > >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > >> calls for n trys. > >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our > >> implementation > >>>>>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Or just give me a week or few to get stack walking working > >> and then > >>>>>>>>>>>> live the regression on other targets? > >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > >> certainly > >>>>>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> It *is* nice to not have have the frontend know about > >> jmpbuf size. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > >> used so easily. > >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>>>>> > >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > >> guess your > >>>>>>>>>>>> point is, you'd rather have n locals, which the backend > >> automatically > >>>>>>>>>>>> merges, than n calls to alloca? > >>>>>>>>>>>> It's not a huge difference -- there are still going to be n > >> calls to > >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, > >> even if > >>>>>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - It could make a maximum of one call to > >> setjmp/pthread_getspecific > >>>>>>>>>>>> per function > >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could > >> keep track > >>>>>>>>>>>> of how many calls it makes per function, > >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I'll still be looking into using the gcc unwinder > >> relatively soon. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already > >> worked maybe? > >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>>>>> I'll do more testing. > >>>>>>>>>>>> > >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for > >> each TRY > >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So the additional inefficiency is multiplied the same as > >> the rest of > >>>>>>>>>>>> the preexisting inefficiency. > >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>>>>> > >>>>>>>>>>>> And second, either way, it could be better. > >>>>>>>>>>>> > >>>>>>>>>>>> Basically, the model should be, that if a function has any > >> try or lock, > >>>>>>>>>>>> it calls setjmp once. > >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>>>>> represents the line number. > >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the > >> integer is > >>>>>>>>>>>> incremented, every time you > >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or > >> rather, the > >>>>>>>>>>>> value can be stored. > >>>>>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>>>>> switches on the integer > >>>>>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>>>>> > >>>>>>>>>>>> This is how other compilers work and it is a fairly simple > >> sensible approach. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more > >> testing and fix > >>>>>>>>>>>> it -- check for NIL. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > >> But now you > >>>>>>>>>>>> are allocating on every TRY where previously the storage > >> was statically > >>>>>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> I've back with full keyboard if more explanation needed. > >> The diff is > >>>>>>>>>>>> actually fairly small to read. > >>>>>>>>>>>> I understand it is definitely less efficient, a few more > >> instructions > >>>>>>>>>>>> for every try/lock. > >>>>>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > >> the change > >>>>>>>>>>>> is written so that it should work > >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. > >> And there > >>>>>>>>>>>> probably is a function call there. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> > >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: > >> the jumpbuf in > >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a > >> jumpbuf. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf > >> aligned to > >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > >> alloca seems > >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > >> currently to see if > >>>>>>>>>>>> the problem is addressed there. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated > >> via a stack > >>>>>>>>>>>> walker. I wanted to do this first though, while more > >> targets using > >>>>>>>>>>>> setjmp. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay/phone > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>>>>> > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't > >> know what > >>>>>>>>>>>> has been done here without diving into the diff. > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> diff attached > >>>>>>>>>>>> > >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Modified files: > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Log message: > >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>>>>> > >>>>>>>>>>>>> to allocate jmp_buf > >>>>>>>>>>>>> > >>>>>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>>>>> > >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety > >> slow path. > >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least > >> with gcc backend. From jkrell at elego.de Fri Jan 7 21:26:44 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:26:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202644.D50812474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:26:44 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Fri Jan 7 21:29:00 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:29:00 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202900.167F32474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:29:00 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Sat Jan 8 05:57:15 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 5:57:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108045715.A9F19CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 05:57:15 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: comments only: "won" => "won the race"; "!" => "." From jkrell at elego.de Sat Jan 8 06:01:20 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:01:20 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108050121.3B57FCC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:01:20 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: leave initMu before calling RegisterFinalCleanup, to avoid deadlock with AtForkPrepare From jay.krell at cornell.edu Sat Jan 8 06:05:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 05:05:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.245 diff -u -r1.245 ThreadPThread.m3 --- ThreadPThread.m3??? 8 Jan 2011 04:57:15 -0000??? 1.245 +++ ThreadPThread.m3??? 8 Jan 2011 04:58:57 -0000 @@ -96,6 +96,7 @@ ?PROCEDURE InitMutex (VAR m: pthread_mutex_t; root: REFANY; ????????????????????? Clean: PROCEDURE(root: REFANY)) = ?? VAR mutex := pthread_mutex_new(); +????? register := FALSE; ?? BEGIN ???? TRY ?????? WITH r = pthread_mutex_lock(initMu) DO <*ASSERT r=0*> END; @@ -103,13 +104,24 @@ ?????? IF m # NIL THEN RETURN END; ?????? (* We won the race, but we might have failed to allocate. *) ?????? IF mutex = NIL THEN RTE.Raise (RTE.T.OutOfMemory) END; -????? RTHeapRep.RegisterFinalCleanup (root, Clean); ?????? m := mutex; ?????? mutex := NIL; +????? register := TRUE; ???? FINALLY ?????? WITH r = pthread_mutex_unlock(initMu) DO <*ASSERT r=0*> END; ?????? pthread_mutex_delete(mutex); ???? END; +??? IF register THEN +????? (* RegisterFinalCleanup serializes itself using RTOS.LockHeap. +???????? Call it outside initMu to avoid deadlock with AtForkPrepare. +???????? Register can happen outside a lock because the root is yet +???????? alive and therefore will not be collected between pthread_mutex_new +???????? and RegisterFinalCleanup. We are careful to only RegisterFinalCleanup +???????? once -- not in the lost race cases -- though it does not clearly +???????? matter. +?????? *) +????? RTHeapRep.RegisterFinalCleanup (root, Clean); +??? END; ?? END InitMutex; ? ?PROCEDURE LockMutex (m: Mutex) = I wonder if we should dispense with initMu and eagerly initialize all mutexes. ?- Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 06:01:20 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare > From jkrell at elego.de Sat Jan 8 06:22:51 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:22:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108052251.34065CC365@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:22:51 Modified files: cm3/m3-sys/cminstall/src/config-no-install/: I386.common Log message: -march=i586 => -march=i686 to fix test case p249: ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [65]) (const_int 0 [0x0])) (set (reg:SI 5 di [63]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg:SI 5 di [63]))) (set (reg/f:SI 4 si [64]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg/f:SI 16 argp))) (set (mem/s/c:BLK (reg:SI 5 di [63]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg/f:SI 16 argp) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [65])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [65]) (expr_list:REG_UNUSED (reg/f:SI 4 si [64]) (expr_list:REG_UNUSED (reg:SI 5 di [63]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 probably merits further investigation From jkrell at elego.de Sat Jan 8 09:15:22 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:15:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108081522.7A4C12474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:15:21 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: more LONGINT subrange problems, this now has 3 internal codegen errors, due to stack type and expected type mismatches From jkrell at elego.de Sat Jan 8 09:37:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:37:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083705.7F8E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:37:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: make errors visible on stdout or stderr, much better now we get: jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) 4 errors encountered (this should probably say 3) compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Sat Jan 8 09:39:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083905.9D49E2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: put back 'self' as 'u' in PutErr, for smaller historical diff From jkrell at elego.de Sat Jan 8 09:39:34 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083934.F0E71CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:34 Modified files: cm3/m3-sys/m3middle/src/: M3RT.m3 Log message: remove unused RoundUp function From jay.krell at cornell.edu Sat Jan 8 09:38:09 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 08:38:09 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108083705.7F8E22474003@birch.elegosoft.com> References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: Index: src/M3CG_Check.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v retrieving revision 1.13 diff -u -r1.13 M3CG_Check.m3 --- src/M3CG_Check.m3??? 1 Nov 2010 09:37:23 -0000??? 1.13 +++ src/M3CG_Check.m3??? 8 Jan 2011 08:36:01 -0000 @@ -57,6 +57,7 @@ ???????? s_push (t: Type) := Stack_Push; ???????? s_repush () := Stack_Repush; ???????? s_empty () := Stack_Empty; +??????? PutErr (a, b, c: TEXT) := PutErr; ?????? OVERRIDES ???????? set_error_handler := set_error_handler; ???????? begin_unit := begin_unit; @@ -185,10 +186,11 @@ ? ?(*--------------------------------------------------------- low level I/O ---*) ? -PROCEDURE PutErr (u: U;? a, b, c: TEXT := NIL) = +PROCEDURE PutErr (self: U;? a, b, c: TEXT := NIL) = ?? BEGIN -??? u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); -??? INC (u.n_errors); +??? self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); +??? self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); +??? INC (self.n_errors); ?? END PutErr; ? ?(*-------------------------------------------------------- stack checking ---*) Hm. I think I could have left "self" named "u". I'll try that... ? - Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 09:37:05 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 09:37:05 > > Modified files: > cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > > Log message: > make errors visible on stdout or stderr, much better > now we get: > jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > --- building in I386_DARWIN --- > > new source -> compiling Main.m3 > "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > 4 errors encountered (this should probably say 3) > compilation failed => not building program "pgm" > Fatal Error: package build failed > From jkrell at elego.de Sun Jan 9 01:10:55 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:10:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001055.9F43A2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:10:55 Modified files: cm3/m3-db/postgres95/src/: m3makefile Log message: only call configure_system_libs if it is defined; config files out of date? From jkrell at elego.de Sun Jan 9 01:11:32 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:11:32 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001133.4EC5F2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:11:32 Modified files: cm3/scripts/python/: upgrade.py Log message: CopyConfigForDevelopment => CopyConfigForDistribution From hosking at cs.purdue.edu Sun Jan 9 01:17:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:17:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare From jay.krell at cornell.edu Sun Jan 9 01:32:11 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 00:32:11 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108050121.3B57FCC37A@birch.elegosoft.com>, Message-ID: Oops, good catch on the leak, and I'll try that now. ?- Jay ---------------------------------------- > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:17:30 -0500 > To: jkrell at elego.de > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. > > Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). > > On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/08 06:01:20 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > > with AtForkPrepare > From jkrell at elego.de Sun Jan 9 01:36:10 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:36:10 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109003611.5C4C2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:36:10 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: go back a versoin, to 1.245 From jkrell at elego.de Sun Jan 9 01:45:31 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:45:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109004531.4CCC3CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:45:31 Modified files: cm3/scripts/python/: upgrade.py Log message: oops From hosking at cs.purdue.edu Sun Jan 9 01:51:58 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:51:58 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From hosking at cs.purdue.edu Sun Jan 9 01:27:44 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:27:44 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <7EC18C1D-B1F2-4948-8369-15591226DCD6@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From jay.krell at cornell.edu Sun Jan 9 02:15:38 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 01:15:38 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> References: <20110108083705.7F8E22474003@birch.elegosoft.com> , <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> Message-ID: Right. I made it "self" to follow the style of "member functions" ("methods", whatever) and then back to "u" for historical stability. Arguably either way. Not a big deal though. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:51:58 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > It always used to be u, not self. > > On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > > > > Index: src/M3CG_Check.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > > retrieving revision 1.13 > > diff -u -r1.13 M3CG_Check.m3 > > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > > @@ -57,6 +57,7 @@ > > s_push (t: Type) := Stack_Push; > > s_repush () := Stack_Repush; > > s_empty () := Stack_Empty; > > + PutErr (a, b, c: TEXT) := PutErr; > > OVERRIDES > > set_error_handler := set_error_handler; > > begin_unit := begin_unit; > > @@ -185,10 +186,11 @@ > > > > (*--------------------------------------------------------- low level I/O ---*) > > > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > > BEGIN > > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > - INC (u.n_errors); > > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > + INC (self.n_errors); > > END PutErr; > > > > (*-------------------------------------------------------- stack checking ---*) > > > > Hm. I think I could have left "self" named "u". I'll try that... > > > > - Jay > > > > > > ---------------------------------------- > >> Date: Sat, 8 Jan 2011 09:37:05 +0000 > >> To: m3commit at elegosoft.com > >> From: jkrell at elego.de > >> Subject: [M3commit] CVS Update: cm3 > >> > >> CVSROOT: /usr/cvs > >> Changes by: jkrell at birch. 11/01/08 09:37:05 > >> > >> Modified files: > >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > >> > >> Log message: > >> make errors visible on stdout or stderr, much better > >> now we get: > >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > >> --- building in I386_DARWIN --- > >> > >> new source -> compiling Main.m3 > >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > >> 4 errors encountered (this should probably say 3) > >> compilation failed => not building program "pgm" > >> Fatal Error: package build failed > >> > > > From jkrell at elego.de Sun Jan 9 03:36:46 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 3:36:46 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109023648.2344ACC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 03:36:46 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap later in ForkPrepare, try to fix deadlock with mutex initialization From hosking at elego.de Sun Jan 9 12:01:49 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:01:49 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110149.DD5C52474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:01:49 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: While holding initMu InitMutex invokes RegisterFinalCleanup which acquires heapMu. Make sure that AtForkPrepare and AtForkParent both acquire/release these mutexes in the same order. From hosking at elego.de Sun Jan 9 12:07:13 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:07:13 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110713.A4384CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:07:13 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors from conflicts. From hosking at elego.de Sun Jan 9 20:56:31 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 20:56:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109195631.58C2FCC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 20:56:31 Modified files: cm3/m3-libs/arithmetic/doc/: backgnd.html Log message: Weird typo: the prefix "stat" was at some point replaced with "statistic", erroneously. From jkrell at elego.de Mon Jan 10 09:03:50 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 10 Jan 2011 9:03:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110110080350.4F9092474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/10 09:03:50 Modified files: cm3/m3-libs/arithmetic/doc/: wpress.txt Log message: "statistic" => "stat" From hosking at elego.de Tue Jan 11 05:56:50 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 5:56:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111045650.61C57247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 05:56:50 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Candidate fix for AtForkPrepare deadlock with InitMutex. From hosking at elego.de Tue Jan 11 06:14:01 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 6:14:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111051402.A39C2247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 06:14:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: initMu before heapMu to avoid potential deadlock between AtForkPrepare and InitMutex. From jkrell at elego.de Tue Jan 11 09:02:05 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 11 Jan 2011 9:02:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111080205.9D8F1CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/11 09:02:05 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: whitespace only: right justify line continuation backslashes This is harder to maintain (write/type) but easier to read. From mika at elego.de Tue Jan 11 16:57:22 2011 From: mika at elego.de (Mika Nystrom) Date: Tue, 11 Jan 2011 16:57:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111155722.830B7CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/11 16:57:22 Added files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 m3makefile m3overrides Log message: thread testing program. compile and run, expect to see output as follows: Writing file...done Creating reader threads...done Creating forker threads...done Creating allocator threads...done running... laziest thread is 1294760062 seconds behind laziest thread is 11 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 8 seconds behind laziest thread is 10 seconds behind laziest thread is 7 seconds behind laziest thread is 8 seconds behind program stops on its own. From hosking at elego.de Wed Jan 12 01:37:59 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 1:37:59 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112003759.AE706CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 01:37:59 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Oops, so-called "fix" last night was completely broken (tired!). [Mika, please try this latest] From jay.krell at cornell.edu Wed Jan 12 02:58:57 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 01:58:57 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110112003759.AE706CC37A@birch.elegosoft.com> References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense with most of the code implementing it, right? ie: no inCritical, no holder, no condition variables? - Jay ---------------------------------------- > Date: Wed, 12 Jan 2011 01:37:59 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/12 01:37:59 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > Oops, so-called "fix" last night was completely broken (tired!). > [Mika, please try this latest] > From jay.krell at cornell.edu Wed Jan 12 03:00:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 02:00:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com>, Message-ID: er, not quite, I forgot there is BroadcastHeap... - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at elego.de; m3commit at elegosoft.com > Date: Wed, 12 Jan 2011 01:58:57 +0000 > Subject: Re: [M3commit] CVS Update: cm3 > > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- > > Date: Wed, 12 Jan 2011 01:37:59 +0000 > > To: m3commit at elegosoft.com > > From: hosking at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: hosking at birch. 11/01/12 01:37:59 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > Oops, so-called "fix" last night was completely broken (tired!). > > [Mika, please try this latest] > > From jkrell at elego.de Wed Jan 12 08:00:34 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 12 Jan 2011 8:00:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112070034.7D36CCC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/12 08:00:34 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: align Jumpbuf_size, which appears needed for Win32 From hosking at cs.purdue.edu Wed Jan 12 18:15:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 12:15:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: <0722C93E-A3B8-493C-A15E-A32ED378F815@cs.purdue.edu> No, not really. Recursive mutexes are not supported on all platforms. Also, in the reql world we will avoid using mutexes in most instances, instead using lock reservation, etc. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 11, 2011, at 8:58 PM, Jay K wrote: > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- >> Date: Wed, 12 Jan 2011 01:37:59 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/12 01:37:59 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 >> >> Log message: >> Oops, so-called "fix" last night was completely broken (tired!). >> [Mika, please try this latest] >> From hosking at elego.de Wed Jan 12 19:16:34 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:16:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181634.89BC2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:16:34 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Can we rely on pthread_mutex_t always being a reference? Perhaps not, so don't use the locks array. From hosking at elego.de Wed Jan 12 19:18:08 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:18:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181808.52D04CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:18:08 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThreadC.c Log message: Eliminate initMu and lock heap instead, to avoid deadlock between InitMutex and AtForkPrepare. From hosking at elego.de Wed Jan 12 19:33:16 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:33:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112183316.3F661CC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:33:16 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors. From hosking at elego.de Thu Jan 13 02:37:40 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 2:37:40 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113013740.B85192474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 02:37:40 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for InitMutex instead of initMu to avoid deadlock between Initmutex and AtForkParent. From jay.krell at cornell.edu Thu Jan 13 02:53:06 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 01:53:06 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113013740.B85192474003@birch.elegosoft.com> References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: I haven't lookd, but it sounds like the idea is, use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? ie. resolve problems in a graph by merging nodes. I was also wondering if, maybe, we can initialize mutexex/condition variables eagerly instead of on-demand? Therefore without locking? I know that currently there's no interface from the generated code to the runtime for that. It's a tradeoff. Presumably/hopefully there are many mutexes and condition variables that are never used, and initializing them would just be a slow down. - Jay ---------------------------------------- > Date: Thu, 13 Jan 2011 02:37:40 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/13 02:37:40 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 > ThreadPThread.m3 > ThreadPThreadC.c > > Log message: > Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for > InitMutex instead of initMu to avoid deadlock between Initmutex and > AtForkParent. > From hosking at cs.purdue.edu Thu Jan 13 03:59:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 21:59:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: <7F42A0FD-D6EC-49BA-889B-3F15158173DD@cs.purdue.edu> On Jan 12, 2011, at 8:53 PM, Jay K wrote: > > I haven't lookd, but it sounds like the idea is, > use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? > ie. resolve problems in a graph by merging nodes. Yes. > I was also wondering if, maybe, we can initialize > mutexex/condition variables eagerly instead of on-demand? > Therefore without locking? Seems overkill for types that inherit from MUTEX but are never used for locking. Also, ultimately a Modula-3 MUTEX won't be one-to-one with pthread mutexes. > I know that currently there's no interface from the > generated code to the runtime for that. > > > It's a tradeoff. Presumably/hopefully there are many > mutexes and condition variables that are never used, > and initializing them would just be a slow down. Precisely. > > > - Jay > > ---------------------------------------- >> Date: Thu, 13 Jan 2011 02:37:40 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/13 02:37:40 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 >> ThreadPThread.m3 >> ThreadPThreadC.c >> >> Log message: >> Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for >> InitMutex instead of initMu to avoid deadlock between Initmutex and >> AtForkParent. >> From hosking at elego.de Thu Jan 13 06:58:48 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 6:58:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113055848.D4DF02474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 06:58:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap/UnlockHeap in case we already did this in RTCollector AtForkPrepare/AtForkParent. From jkrell at elego.de Thu Jan 13 15:58:29 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 13 Jan 2011 15:58:29 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113145829.72EAD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/13 15:58:29 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: __builtin_alloca didn't work w/o translation among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca and do the comparison by pointer equality (since gcc uses string interning) I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near anything else. From jay.krell at cornell.edu Thu Jan 13 16:00:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:00:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113145829.72EAD2474003@birch.elegosoft.com> References: <20110113145829.72EAD2474003@birch.elegosoft.com> Message-ID: Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 13 16:06:37 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:06:37 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113145829.72EAD2474003@birch.elegosoft.com>, Message-ID: Hm. I'll try the hashtable instead. - Jay From: jay.krell at cornell.edu To: jkrell at elego.de; m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 13 Jan 2011 15:00:24 +0000 Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at elego.de Thu Jan 13 19:16:48 2011 From: mika at elego.de (Mika Nystrom) Date: Thu, 13 Jan 2011 19:16:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113181648.6D80ECC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/13 19:16:48 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: updated documentation/in-line comments for thread testing program to describe design and usage of program From jkrell at elego.de Fri Jan 14 08:19:39 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 14 Jan 2011 8:19:39 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114071939.5EEB8CC10F@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/14 08:19:39 Modified files: cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: There is no need to put all/any of the builtins into a hashtable. All of the uses are very direct/special, except for m3_alloca. That is, the frontend doesn't generate regular function calls to any of them, except m3_alloca. From mika at elego.de Fri Jan 14 14:52:05 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 14:52:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114135206.1F33F2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 14:52:05 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Make diagnostic output snazzier. Now prints median and minimum ages as well as maximum age, for each category of threads. From mika at elego.de Fri Jan 14 15:05:37 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:05:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140537.688332474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:05:37 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Even snazzier: ignore exceptions that happen during setup, print diagnostics for exceptions that happen during running, and eliminate all compiler warnings. From mika at elego.de Fri Jan 14 15:09:02 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:09:02 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140902.199AD2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:09:02 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Fix comments to match code. From mika at elego.de Sat Jan 15 14:39:09 2011 From: mika at elego.de (Mika Nystrom) Date: Sat, 15 Jan 2011 14:39:09 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110115133909.E6F07CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/15 14:39:09 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Add a fourth class of threads to thread tester: thread-creator threads. From mika at elego.de Sun Jan 16 02:18:27 2011 From: mika at elego.de (Mika Nystrom) Date: Sun, 16 Jan 2011 2:18:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116011827.DD31F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/16 02:18:27 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: give the user something to look at while the program runs (also shows off deadlock well) From dabenavidesd at yahoo.es Sun Jan 16 03:27:40 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 02:27:40 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116011827.DD31F2474003@birch.elegosoft.com> Message-ID: <19786.44534.qm@web29702.mail.ird.yahoo.com> Hi all: Yes, sure just that we need also for range checks and type checks, I mean, I guess the problem are not the client programs by itself if so why do you think they crashed unsafely? The problem is to test the implementation more deeply, perhaps Tony is the best man to do that part of the job I think. However unsafe code there is guaranteed by others to be right, I tend to feel that in those cases a more detailed test compliance is needed, I mean, we don't guarantee every platform behaves exactly as we think of it. Perhaps Jay could be indicated for that part of the job, I think. Thanks in advance --- El s?b, 15/1/11, Mika Nystrom escribi?: > De: Mika Nystrom > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:18 > CVSROOT: /usr/cvs > Changes by: mika at birch. > 11/01/16 02:18:27 > > Modified files: > cm3/m3-libs/m3core/tests/thread/src/: > Main.m3 > > Log message: > give the user something to look at while > the program runs (also shows off deadlock well) > > From dabenavidesd at yahoo.es Sun Jan 16 04:36:23 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 03:36:23 +0000 (GMT) Subject: [M3commit] [M3devel] CVS Update: cm3 In-Reply-To: <19786.44534.qm@web29702.mail.ird.yahoo.com> Message-ID: <878606.72309.qm@web29713.mail.ird.yahoo.com> Hi all: The best source of a check for both cases is a test set for Modula-3 vs C threading programs. I mean what source of it might come to crash if we allow just normal range and type checking by itself on the Modula-3 programs, just C part that we don't have, I assume the Modula-3 parts touching it are thread safe as it's the collector, if a program is to crash badly, it should crash in the Modula-3 version and be unsafely crashed at a certain level on C in some cases (sort of the exceptional cases), I'm more interested that it doesn't crash on both sides, sort of being a good M3 behaved guy, that is, what it would mean is we do have a problem on the threading library implementation (not tested, unmarked exception, or uncaught ones?), given platforms behave well, that sometimes I think they do, but we don't know, that's why we need test some assertions if so (not generate the code if you want to run assembly smoothly sure). Perhaps the best approach here is just to test it right goes into C mode and then is just part of the safe modules to guard type check the bad inputs or outputs ISTYPE() is a good way of doing it if you may allow me say. Thanks in advance. --- El s?b, 15/1/11, Daniel Alejandro Benavides D. escribi?: > De: Daniel Alejandro Benavides D. > Asunto: Re: [M3devel] [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com, mika at elego.de, m3devel at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:27 > Hi all: > Yes, sure just that we need also for range checks and type > checks, I mean, I guess the problem are not the client > programs by itself if so why do you think they crashed > unsafely? > The problem is to test the implementation more deeply, > perhaps Tony is the best man to do that part of the job I > think. > However unsafe code there is guaranteed by others to be > right, I tend to feel that in those cases a more detailed > test compliance is needed, I mean, we don't guarantee every > platform behaves exactly as we think of it. Perhaps Jay > could be indicated for that part of the job, I think. > Thanks in advance > > --- El s?b, 15/1/11, Mika Nystrom > escribi?: > > > De: Mika Nystrom > > Asunto: [M3commit] CVS Update: cm3 > > Para: m3commit at elegosoft.com > > Fecha: s?bado, 15 de enero, 2011 21:18 > > CVSROOT: /usr/cvs > > Changes by: > mika at birch. > > 11/01/16 02:18:27 > > > > Modified files: > > > cm3/m3-libs/m3core/tests/thread/src/: > > Main.m3 > > > > Log message: > > give the user something to > look at while > > the program runs (also shows off deadlock well) > > > > > > > > From hosking at elego.de Sun Jan 16 20:58:37 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 20:58:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116195837.5997B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 20:58:37 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: No need to LockHeap/UnlockHeap at fork. Simply reset flags recording threads started. From hosking at elego.de Sun Jan 16 21:02:17 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:02:17 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200217.B82172474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:02:17 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: Eliminate AtForkPrepare and AtForkParent. From hosking at elego.de Sun Jan 16 21:06:48 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:06:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200648.58E012474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:06:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Reinstate initMu. LockHeap should never be called before locking any of activeMu, slotsMu, initMu, perfMu. From hosking at elego.de Sun Jan 16 22:25:21 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 22:25:21 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116212521.EEE5F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 22:25:21 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: One more deadlock between activeMu and LockHeap. SuspendOthers can be called while LockHeap, which then locks activeMu. From mika at elego.de Mon Jan 17 05:58:56 2011 From: mika at elego.de (Mika Nystrom) Date: Mon, 17 Jan 2011 5:58:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110117045856.65FE62474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/17 05:58:56 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: add a fifth type of thread---"locker" thread. From jay.krell at cornell.edu Mon Jan 17 06:42:12 2011 From: jay.krell at cornell.edu (jay.krell at cornell.edu) Date: Sun, 16 Jan 2011 21:42:12 -0800 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116195837.5997B2474003@birch.elegosoft.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> Message-ID: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). - Jay On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/16 20:58:37 > > Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 > > Log message: > No need to LockHeap/UnlockHeap at fork. > Simply reset flags recording threads started. > From hosking at cs.purdue.edu Mon Jan 17 13:55:57 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 17 Jan 2011 07:55:57 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> Message-ID: <08342311-619A-443A-9685-97E5BD6E9404@cs.purdue.edu> It gets locked in ThreadPThread atfork. Sent from my iPhone On Jan 17, 2011, at 12:42 AM, jay.krell at cornell.edu wrote: > I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). > > - Jay > > On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/16 20:58:37 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 >> >> Log message: >> No need to LockHeap/UnlockHeap at fork. >> Simply reset flags recording threads started. >> From rodney at elego.de Tue Jan 18 03:21:42 2011 From: rodney at elego.de (Rodney M. Bates) Date: Tue, 18 Jan 2011 3:21:42 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110118022143.132DC2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: rodney at birch. 11/01/18 03:21:42 Modified files: cm3/m3-sys/m3gdb/gdb/gdb/: Tag: release_branch_cm3_5_8 i386-tdep.c Log message: An incomplete fix to get results of floating type working on m3gdb-typed calls to functions. This needs extensive rework. m3gdb borrows heavily from gdb for handling floating values. But gdb has only one floating type code (TYPE_CODE_FLT) and it distinguishes the different floating types by size. This is not really sufficient for M3, because there are 3 floating types, not necessarily all the same size. New type codes for M3 have been in here for years, but many places in existing gdb code need to recognize them. Also, existing gdb printing and other handling of floating values may not be exacly right for m3gdb anyway. It might be nice to just call M3 code in, e.g., Fmt. From jkrell at elego.de Sat Jan 22 20:39:19 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 22 Jan 2011 20:39:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110122193919.A61892474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/22 20:39:19 Modified files: cm3/m3-sys/m3cc/gcc-4.5/include/: libiberty.h Log message: #include libgen.h instead of declaring basename From jkrell at elego.de Sun Jan 30 11:41:48 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 30 Jan 2011 11:41:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110130104149.4129F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/30 11:41:48 Modified files: cm3/m3-sys/m3front/src/misc/: CG.i3 Log message: remove one newline From jkrell at elego.de Mon Jan 3 14:14:25 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:14:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103131425.63E4A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:14:25 Removed files: cm3/m3-libs/m3core/src/runtime/SPARC64_SOLARIS/: RTMachine.i3 m3makefile Log message: remove unused files From jkrell at elego.de Mon Jan 3 14:26:53 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:26:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103132656.309102474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:26:53 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapStats.i3 Log message: one newline at end of file suffices From jkrell at elego.de Mon Jan 3 14:57:45 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 14:57:45 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103135745.B1B6A2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 14:57:45 Modified files: cm3/m3-libs/m3core/src/runtime/ALPHA_OSF/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/SOLsun/: RTMachine.i3 cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 RTMachine.i3 Log message: Use 64K pages everywhere -- less target dependent code, basically. The page size used to be target dependent when the garbage collector interacted with virtual memory. Now it is basically not machine dependent, except that on Windows we use VirtualAlloc, which always allocates on 64K boundaries, even if you ask for less than 64K, so allocation less than 64K ends up completely wasting memory. This could be viewed negatively as giving the Windows-dependent value to all targets. But I think it is ok. From jkrell at elego.de Mon Jan 3 15:05:36 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:05:36 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103140536.2BCBD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:05:36 Removed files: cm3/m3-libs/m3core/src/runtime/DS3100/: RTMachine.i3 RTStackASM.s RTStackC.c m3makefile Log message: This code has a high ratio of bug workarounds and reverse engineering. And it is long dead -- I believe it is for Ultrix on MIPS. Delete it. If someone brings back Ultrix (in an emulator?)... From jkrell at elego.de Mon Jan 3 15:13:04 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 3 Jan 2011 15:13:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110103141304.4E7262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/03 15:13:04 Modified files: cm3/m3-libs/m3core/src/runtime/NT386/: m3makefile cm3/m3-libs/m3core/src/runtime/common/: m3makefile Removed files: cm3/m3-libs/m3core/src/runtime/NT386/: RTMachine.i3 Log message: use common RTMachine.i3 From jkrell at elego.de Tue Jan 4 12:21:56 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 12:21:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104112156.2F9952474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 12:21:56 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTHeapRep.i3 Log message: fix warning: remove unused import RTMachine From jkrell at elego.de Tue Jan 4 13:48:34 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 13:48:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104124834.AF0222474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 13:48:34 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 cm3/m3-libs/m3core/src/C/: m3makefile cm3/m3-libs/m3core/src/C/Common/: m3makefile cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 Added files: cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 Removed files: cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile Log message: Set jumpbuf_align to 64 for all targets. We'd really like to use 2 * BYTESIZE(INTEGER) for all targets except PPC_LINUX, but that isn't expressible. This is therefore as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, and non-ideal for PPC_LINUX, roughly the same as it ever was (well, the middle end got it right, but the runtime didn't, and they do need to match; so it was seemingly wrong, but somehow worked on PPC_LINUX) In future, hopefully, compiler will inject the type instead of depending on it being declared elsewhere in Modula-3. In future, hopefully, this code will fall away on the majority of platforms/users -- i.e. if we use the gcc stack walker. But it will still stay around in some form for portability to non-gcc platforms. So injecting the type is still desirable. This removes lots of target-dependence. This has the downside of introducing an extra 4 bytes of unnecessary frame size on platforms where 4 byte alignment of jmpbuf is sufficient. (Note that we have and continue to bloat the jmpbuf for other reasons. - sometimes it was sigjmpbuf, no longe - sometimes it is plain wrong, e.g. LINUXLIBC6, still - sometimes for hypothetical interop e.g. NT <=> Interix) If RaiseActivation were one more or one less word, or if the frame has an otherwise odd number of words, the wastage should be removable by offseting the location of RaiseActivation. That is, alignment should be achievable by via hole, but via offseting the enclosing base and possibly using the hole that that creates. In either case, I'm inclined to go one step further and pass an extern const to alloca and only put a pointer to the jmpbuf in the "EF1", dramatically further eliminating target-dependence. We are already calling pthread_getspecific and setjmp, so alloca seems maybe a further reasonable deoptimization in an already slow path. Perhaps we could somehow combine the calls (not easy, given how setjmp and alloca are so special). This would presumably also address the alignment problem -- assuming alloca knows to return a pointer aligned enough for "anything", i.e. including a jmpbuf. There are still some platform-dependent Csetjmp.i3 files (NT) in order to call longjmp instead of the more common _longjmp. Testing, reading headers, and/or disasm will hopefully show that such platforms have _longjmp and it is equivalent. Soon. From jkrell at elego.de Tue Jan 4 14:04:53 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:04:53 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104130453.9D7152474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:04:53 Modified files: cm3/m3-sys/m3middle/src/: Target.m3 Log message: fix comment: "efficient" => "inefficient" From jay.krell at cornell.edu Tue Jan 4 14:03:17 2011 From: jay.krell at cornell.edu (Jay K) Date: Tue, 4 Jan 2011 13:03:17 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110104124834.AF0222474003@birch.elegosoft.com> References: <20110104124834.AF0222474003@birch.elegosoft.com> Message-ID: straightforward diff attached > Date: Tue, 4 Jan 2011 13:48:34 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/04 13:48:34 > > Modified files: > cm3/m3-sys/m3middle/src/: Target.m3 > cm3/m3-libs/m3core/src/C/: m3makefile > cm3/m3-libs/m3core/src/C/Common/: m3makefile > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > Added files: > cm3/m3-libs/m3core/src/C/Common/: COPYRIGHT Csetjmp.c Csetjmp.i3 > Removed files: > cm3/m3-libs/m3core/src/C/ALPHA32_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA64_VMS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ALPHA_OSF/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_FREEBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/AMD64_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARMEL_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/ARM_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/FreeBSD4/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_FREEBSD/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_INTERIX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/I386_NETBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/I386_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/LINUXLIBC6/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64EL_OPENBSD/: Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/MIPS64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/NetBSD2_i386/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA32_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PA64_HPUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC32_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC64_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_DARWIN/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/PPC_LINUX/: COPYRIGHT Csetjmp.i3 > m3makefile > cm3/m3-libs/m3core/src/C/SOLgnu/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SOLsun/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC32_SOLARIS/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_LINUX/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_OPENBSD/: Csetjmp.i3 m3makefile > cm3/m3-libs/m3core/src/C/SPARC64_SOLARIS/: Csetjmp.i3 m3makefile > > Log message: > Set jumpbuf_align to 64 for all targets. > > We'd really like to use 2 * BYTESIZE(INTEGER) for all targets > except PPC_LINUX, but that isn't expressible. This is therefore > as far as we know, incorrect for PA64_HPUX and SPARC64_SOLARIS, > and non-ideal for PPC_LINUX, roughly the same as it ever was > (well, the middle end got it right, but the runtime didn't, > and they do need to match; so it was seemingly wrong, but > somehow worked on PPC_LINUX) > > In future, hopefully, compiler will inject the type instead > of depending on it being declared elsewhere in Modula-3. > > In future, hopefully, this code will fall away on the majority > of platforms/users -- i.e. if we use the gcc stack walker. > But it will still stay around in some form for portability > to non-gcc platforms. So injecting the type is still desirable. > > This removes lots of target-dependence. > This has the downside of introducing an extra 4 bytes of unnecessary > frame size on platforms where 4 byte alignment of jmpbuf is sufficient. > (Note that we have and continue to bloat the jmpbuf for other reasons. > - sometimes it was sigjmpbuf, no longe > - sometimes it is plain wrong, e.g. LINUXLIBC6, still > - sometimes for hypothetical interop e.g. NT <=> Interix) > > If RaiseActivation were one more or one less word, > or if the frame has an otherwise odd number of words, > the wastage should be removable by offseting the location > of RaiseActivation. That is, alignment should be achievable > by via hole, but via offseting the enclosing base and > possibly using the hole that that creates. > > In either case, I'm inclined to go one step further and pass > an extern const to alloca and only put a pointer to the jmpbuf > in the "EF1", dramatically further eliminating target-dependence. > We are already calling pthread_getspecific and setjmp, so alloca > seems maybe a further reasonable deoptimization in an already slow path. > Perhaps we could somehow combine the calls (not easy, given > how setjmp and alloca are so special). This would presumably > also address the alignment problem -- assuming alloca knows > to return a pointer aligned enough for "anything", i.e. including > a jmpbuf. > > There are still some platform-dependent Csetjmp.i3 files (NT) > in order to call longjmp instead of the more common _longjmp. > Testing, reading headers, and/or disasm will hopefully show > that such platforms have _longjmp and it is equivalent. Soon. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf64.txt URL: From jkrell at elego.de Tue Jan 4 14:14:52 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:14:52 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131452.1DA622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:14:52 Added files: cm3/scripts/config/: alloca_alignment.c Log message: program to see how aligned alloca() result is From jkrell at elego.de Tue Jan 4 14:15:11 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:15:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104131511.F3A3D2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:15:11 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: show more bits From jkrell at elego.de Tue Jan 4 14:23:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 14:23:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104132325.5B1682474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 14:23:25 Modified files: cm3/scripts/config/: alloca_alignment.c Log message: alloca.h on some platforms needed, e.g. Solaris From jkrell at elego.de Tue Jan 4 20:27:25 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 20:27:25 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104192725.362E32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 20:27:25 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: Makefile.in tree-ssa-loop.c cm3/m3-sys/m3cc/src/: clean_marker.txt Removed files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-loop-linear.c Log message: Remove tree-loop-linear optimization pass, which the gcc developers are considering removing since it is apparently broken. See http://gcc.gnu.org/ml/gcc/2011-01/msg00056.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00133.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00143.html http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00146.html cleanup a little graphite stuff (graphite/cloog/ppl refers to loop optimizations in gcc that are dependent upon additional libraries being available, similar to the situation with gmp/mpfr/mpc, but that they are optional even in unpatched gcc) From jkrell at elego.de Tue Jan 4 21:43:37 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:43:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204337.97F562474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:43:37 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: ipa-reference.c tree-vect-stmts.c Log message: fix warnings by removing unused function and locals From jkrell at elego.de Tue Jan 4 21:47:27 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 4 Jan 2011 21:47:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110104204727.E9BB82474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/04 21:47:27 Modified files: cm3/m3-sys/m3cc/gcc-4.5/gcc/: tree-ssa-loop-niter.c Log message: fix some warnings, ATTRIBUTE_UNUSED on unused parameters From jkrell at elego.de Wed Jan 5 15:08:19 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:08:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105140819.DE2A1CC110@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:08:19 Modified files: cm3/m3-sys/m3back/src/: M3C.m3 Log message: flush minor change that was sitting around, not yet really in use From jkrell at elego.de Wed Jan 5 15:16:04 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:16:04 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141604.2D23C2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:16:04 Modified files: cm3/scripts/config/: stack_direction.c Log message: flush minor change: make it look just like m3core From jkrell at elego.de Wed Jan 5 15:17:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:17:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141751.9A9622474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:17:51 Modified files: cm3/scripts/config/: stack_direction.c Log message: more like m3core From jkrell at elego.de Wed Jan 5 15:19:28 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:19:28 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105141928.30CB32474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:19:28 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: comments only From jkrell at elego.de Wed Jan 5 15:20:03 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:20:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142003.5C442CC123@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:20:03 Modified files: cm3/m3-libs/m3core/src/thread/Common/: ThreadInternal.c Log message: another possible inline suppression From jkrell at elego.de Wed Jan 5 15:21:51 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:21:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142151.23B672474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:21:51 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: const => EXTERN_CONST This makes it mean the same thing in all C and C++ compilers. Just plain "extern const" would do the same, but that gcc warns for this correct unambiguous portable usage.. From jkrell at elego.de Wed Jan 5 15:25:37 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:25:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105142537.AB0932474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:25:37 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: whitespace only, so that subsequent change lines up w/o adding the whitespace change From jkrell at elego.de Wed Jan 5 15:34:55 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 15:34:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105143455.087E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 15:34:55 Modified files: cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 Log message: use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); alloca(Csetjmp__Jumpbuf_size) to allocate jmp_buf - eliminates a large swath of target-dependent code - allows for covering up the inability to declare types with alignment > 64 bits It is, granted, a little bit slower, in an already prety slow path. Note that alloca isn't actually a function call, at least with gcc backend. From jay.krell at cornell.edu Wed Jan 5 15:37:12 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 14:37:12 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105143455.087E22474003@birch.elegosoft.com> References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: jmpbuf_alloca.txt URL: From jkrell at elego.de Wed Jan 5 18:32:01 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 5 Jan 2011 18:32:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110105173201.5A1742474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/05 18:32:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: Don't use __thread on Solaris. It failed to link. See: http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console From dabenavidesd at yahoo.es Wed Jan 5 19:10:27 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 18:10:27 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110105173201.5A1742474003@birch.elegosoft.com> Message-ID: <167906.41482.qm@web29707.mail.ird.yahoo.com> Hi all: Are this failures linked to a trac ticket with an appropriate tag, would be a quality of service improvement to link to it automatically? I think if the failures of compiler, system compiler, compiler back end, linker, system linker or checker and/or theorem prover, we should produce automatically a ticket assigned for the "guilty" or some else if so, so one can be warned more directly and solve it accordingly, what do you think? I assume some simple changes are or can be back up if so there is a clear compile time error cause and solution. But for everything else is good? I mean might be the ideal with wiki service open we can improve documentation and process on it. Thanks in advance --- El mi?, 5/1/11, Jay Krell escribi?: > De: Jay Krell > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: mi?rcoles, 5 de enero, 2011 13:32 > CVSROOT: /usr/cvs > Changes by: > jkrell at birch. 11/01/05 18:32:01 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: > ThreadPThreadC.c > > Log message: > Don't use __thread on Solaris. > It failed to link. > See: > http://hudson.modula3.com:8080/job/cm3-current-build-SOLsun-opencsw-current9s/166/console > > From hosking at cs.purdue.edu Wed Jan 5 19:35:59 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 13:35:59 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> Message-ID: Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 21:44:08 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 20:44:08 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 5 23:40:25 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 5 Jan 2011 22:40:25 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Thu Jan 6 00:31:08 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Wed, 5 Jan 2011 23:31:08 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: Message-ID: <381607.89212.qm@web29720.mail.ird.yahoo.com> Hi all: I wonder how we could make the static M3CG stack allocation tracing verified so not overflow can occur and so make a progress with that compiler obligation too. I suppose every thing we can put in the stack instead of the heap is less efficient in compiler and the checker times but in terms of execution less slower than it would without it. I recall just an experiment with the ESC to check DISPOSE statement (side effecting) instruction will not corrupt the heap with the ESC, kind of interesting for the help M3CG to disable compiler inserted useless garbage collector calls and if so usable inside the stack boundaries for checking unused stack allocated callee? for instance inside the bug commented by Mika on see: https://mail.elegosoft.com/pipermail/m3devel/2010-December/008330.html perhaps a mapping of the M3CG typed implementation if we have already a reference to that unreachable code and if so will it be called or not according to the compiler code generator, in such a case there is a on-live dynamic linking it will just like it could prove it or not to not disable those callers, we would need to automatically infer the annotations for the checker to M3CG ?-instructions and feed for the checker and prover that too. This would be useful not just for the compiler, but for the programmer too, don't you think? Also this would be straightforward to demonstrative of a program that is not to overflow or underflow by popping out anyhow, another missing check in current compilers technology as of what I currently know. Besides that one must check the arithmetic overflow, that would need more of the ESC normal technology by now, though we could explicitly check for it in the searched errors too, again typing the M3CG ?-instructions will gave some of the neeeded info I guess and by emulating ALU logic we could also warn proof that anything would happen in some point if contracts are fulfilled. ?? Thanks in advance --- El mi?, 5/1/11, Jay K escribi?: De: Jay K Asunto: Re: [M3commit] CVS Update: cm3 Para: "Tony" CC: m3commit at elegosoft.com Fecha: mi?rcoles, 5 de enero, 2011 17:40 I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. ?- Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 #yiv448101372 .yiv448101372ExternalClass .yiv448101372ecxhmmessage P {padding:0px;} #yiv448101372 .yiv448101372ExternalClass body.yiv448101372ecxhmmessage {font-size:10pt;font-family:Tahoma;} I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? ?I don't know what has been done here without diving into the diff. Antony Hosking?|?Associate Professor?| Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice?+1 765 494 6001 |?Mobile?+1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote: diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To:?m3commit at elegosoft.com > From:?jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 >? > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 >? > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3? > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3? > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3? > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c? > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c? > cm3/m3-sys/m3front/src/misc/: Marker.m3? > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3? > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3? >? > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) >? > to allocate jmp_buf >? > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits >? > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. >? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 01:17:01 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:17:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106001701.1620F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:17:00 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Main.m3 m3makefile Log message: a test case from Mika currently results in: new source -> compiling Main.m3 "../Main.m3", line 21: warning: potentially unhandled exception: OSError.E "../Main.m3", line 18: warning: potentially unhandled exception: Thread.Alerted "../Main.m3", line 16: warning: not used (DumpOne) "../Main.m3", line 15: warning: not used (DumpMatching) 4 warnings encountered ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [66]) (const_int 0 [0x0])) (set (reg:SI 1 dx [64]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 1 dx [64]))) (set (reg:SI 4 si [65]) (plus:SI (ashift:SI (reg:SI 0 ax [66]) (const_int 2 [0x2])) (reg:SI 4 si [65]))) (set (mem/s/c:BLK (reg:SI 1 dx [64]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg:SI 4 si [65]) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [66])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [66]) (expr_list:REG_UNUSED (reg:SI 4 si [65]) (expr_list:REG_UNUSED (reg:SI 1 dx [64]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. m3_backend => 4 m3cc (aka cm3cg) failed compiling: Main.mc compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:25:08 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:25:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002508.623F92474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:25:08 Added files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 m3makefile Log message: another test case from Mika jbook2:p250 jay$ cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 1: 1 code generation error 1 error encountered compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Thu Jan 6 01:26:15 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 1:26:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106002615.77E782474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 01:26:15 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: slightly simpler, same error From hosking at cs.purdue.edu Thu Jan 6 02:21:11 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:21:11 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com> , Message-ID: <3AC78E33-81AB-49EF-B566-468EF601BC36@cs.purdue.edu> Do you alloca on every TRY or once in procedures that have a TRY? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 3:44 PM, Jay K wrote: > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 02:23:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:23:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , Message-ID: Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote: > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:25:03 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:25:03 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106012503.90C392474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:25:03 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: much simpler, same error From jay.krell at cornell.edu Thu Jan 6 02:33:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 01:33:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 02:33:51 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:33:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013351.4AB262474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:33:51 Modified files: cm3/m3-sys/m3tests/src/: Test.i3 TestC.c Log message: fix now that Csetjmp is unsafe, and that we don't need to check the size of jmpbuf From jkrell at elego.de Thu Jan 6 02:38:38 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 2:38:38 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106013838.D102B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 02:38:38 Added files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 m3makefile Log message: starting some new test code to nail down try/finally/except/lock stuff not yet done, taking short break From hosking at cs.purdue.edu Thu Jan 6 02:49:24 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 20:49:24 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , Message-ID: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote: > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 03:08:47 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 02:08:47 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 03:14:17 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 5 Jan 2011 21:14:17 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> Message-ID: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 03:32:11 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 3:32:11 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106023211.9CC57CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 03:32:11 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: work in progress From jkrell at elego.de Thu Jan 6 04:42:30 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 4:42:30 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106034231.3E0E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 04:42:30 Added files: cm3/m3-sys/m3tests/src/p2/p249/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p250/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 cm3/m3-sys/m3tests/src/p2/p251/: Tag: release_branch_cm3_5_8 m3makefile Main.m3 Log message: perhaps slightly controversial: add new tests in old branch This is a little easier to test/compare and the downside should be negligible -- downside of polluting history. From jay.krell at cornell.edu Thu Jan 6 05:52:33 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 04:52:33 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 07:02:26 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 06:02:26 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 08:18:41 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 8:18:41 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106071841.7E2072474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 08:18:41 Modified files: cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 cm3/m3-libs/m3core/src/runtime/ex_stack/: RTExStack.m3 Log message: comments only; in particular put in "see also" indicating these files describe each other From hosking at cs.purdue.edu Thu Jan 6 15:19:36 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:19:36 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu> , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu> Message-ID: <6DAAF11E-4EA3-4D9E-BFBE-4B15D2B873F5@cs.purdue.edu> No, if there are n static TRY block sites, then up to n calls to alloca is OK. I am assuming you test for NIL at each site and alloca only if NIL. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 11:52 PM, Jay K wrote: > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 6 15:22:09 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 09:22:09 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, Message-ID: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. 2. If not, then alloca and save its pointer in the local variable 3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 17:29:44 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 17:29:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106162944.39C442474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 17:29:44 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: more tests From jay.krell at cornell.edu Thu Jan 6 17:35:43 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 16:35:43 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. I guess, really, it is EF1, EF2, etc. So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. something like: PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; => void F1() { jmp_buf* jb = 0; EF1 a,b,c; setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 do stuff 1... setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 do stuff 2... setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 do stuff 3... } (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) Still, something I can't pin down strikes me as too simple here. If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. That doesn't seem adequate. What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? It won't know where to resume, right? It's just keep longjmping to the same place. In the Visual C++ runtime, there is "local unwind" and "global unwind". "local unwind" is like, "within the same functin", "global unwind" is across functions. I think somehow that is related here. e.g. how would you ensure forward progress in this: EXCEPTION E1; EXCEPTION E2; EXCEPTION E3; PROCEDURE F4() RAISES ANY = CONST Function = "F4 "; BEGIN Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); TRY Put(Function & Int(Line())); NL(); RAISE E1; EXCEPT ELSE RAISE E2; END; EXCEPT ELSE RAISE E3; END; EXCEPT ELSE END; END F4; Oddly in my test p251, the stack depth is not increased by TRY. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Thu, 6 Jan 2011 09:22:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu I am OK with what you have currently: At each TRY: 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL.2. If not, then alloca and save its pointer in the local variable3. Execute the try block. As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. On Jan 6, 2011, at 1:02 AM, Jay K wrote: > Code size will suffer. Indeed. Unoptimized code size does suffer a lot, in functions that use try. Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still portable implementation doesn't seem too too difficult. Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? Using a local integer to record the position within the function? Or just give me a week or few to get stack walking working and then live the regression on other targets? (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) It *is* nice to not have have the frontend know about jmpbuf size. I looked into the "builtin_setjmp" stuff, but it can't be used so easily. It doesn't work for intra-function jumps, only inter-function. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 6 Jan 2011 04:52:33 +0000 Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. The alloca calls will be dwarfed. Code size will suffer. And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. - It could make a maximum of one call to setjmp/pthread_getspecific per function - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, issue a multiplication, and offset each jmpbuf. It is a tradeoff. So, yes, given my current understanding, it is progress. The target-dependence is not worth it, imho. I'll still do some comparisons to release. I'll still be looking into using the gcc unwinder relatively soon. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 21:14:17 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu On Jan 5, 2011, at 9:08 PM, Jay K wrote:Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. I'll do more testing. Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. And the preexisting inefficiency is way more than the increase. And second, either way, it could be better. Basically, the model should be, that if a function has any try or lock, it calls setjmp once. And then, it should have one volatile integer, that in a sense represents the line number. But not really. It's like, every time you cross a TRY, the integer is incremented, every time you cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. And then there is a maximum of one one handler per function, it switches on the integer to decide where it got into the function and what it should do. This is how other compilers work and it is a fairly simple sensible approach. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:49:24 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Note that you need a different jmpbuf for each nested TRY! Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 8:33 PM, Jay K wrote:oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. - Jay Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:23:09 -0500 CC: m3commit at elegosoft.com To: jay.krell at cornell.edu Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? On Jan 5, 2011, at 5:40 PM, Jay K wrote:I've back with full keyboard if more explanation needed. The diff is actually fairly small to read.I understand it is definitely less efficient, a few more instructions for every try/lock.No extra function call, at least with gcc backend.I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should workbut I have to test it to be sure, will to roughly tonight. And there probably is a function call there. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 20:44:08 +0000 CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. - Jay/phone Subject: Re: [M3commit] CVS Update: cm3 From: hosking at cs.purdue.edu Date: Wed, 5 Jan 2011 13:35:59 -0500 CC: jkrell at elego.de; m3commit at elegosoft.com To: jay.krell at cornell.edu Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 5, 2011, at 9:37 AM, Jay K wrote:diff attached > Date: Wed, 5 Jan 2011 15:34:55 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/05 15:34:55 > > Modified files: > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > Log message: > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > alloca(Csetjmp__Jumpbuf_size) > > to allocate jmp_buf > > - eliminates a large swath of target-dependent code > - allows for covering up the inability to declare > types with alignment > 64 bits > > It is, granted, a little bit slower, in an already prety slow path. > Note that alloca isn't actually a function call, at least with gcc backend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jkrell at elego.de Thu Jan 6 18:08:47 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 18:08:47 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106170847.442592474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 18:08:47 Modified files: cm3/m3-sys/m3tests/src/p2/p251/: Main.m3 Log message: aha! loop with try, not good From hosking at cs.purdue.edu Thu Jan 6 19:52:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 13:52:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> Message-ID: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> You can't have one jmpbuf per procedure. You need one per TRY scope, since they can be nested. On Jan 6, 2011, at 11:35 AM, Jay K wrote: > Hm. How do I single instance the "EF1"? The current code allocates a local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the existance of the ternary operator, and that it only evaluates one side or the other, and that assignment is expression..I quite like those features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of additional progress, you only ever know the last place you were in a function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your point is, you'd rather have n locals, which the backend automatically merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific per function > - The calls to alloca could be merged. The frontend could keep track of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, it calls setjmp once. > And then, it should have one volatile integer, that in a sense represents the line number. > But not really. It's like, every time you cross a TRY, the integer is incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the value can be stored. > And then there is a maximum of one one handler per function, it switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix it -- check for NIL. > > - Jay > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you are allocating on every TRY where previously the storage was statically allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is actually fairly small to read. > I understand it is definitely less efficient, a few more instructions for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there probably is a function call there. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in EF1 is now allocated with alloca, and a pointer stored. It is definitely a bit less efficient, but the significant advantage is frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to more than 64 bits. I at least checked on Linux/PowerPC and alloca seems to align to 16 bytes. I don't have an HPUX machine currently to see if the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack walker. I wanted to do this first though, while more targets using setjmp. > > - Jay/phone > > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 6 20:00:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 19:00:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: I believe you can, but it'd take significant work in the frontend. The jmpbuf should identify merely which procedure/frame to return to. There would also be a volatile local integer, that gets altered at certain points through the function. When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. Instead of setjmp, the compiler pessimizes appropriately. So the result is that a function with one or more tries, or one or more locals with destructors, puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate where in the function it is. If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. It is more work through, granted, I can understand that. And given that we have a much better option for many platforms, the payoff would be reduced. Anyway, I'm trying what you say, like for TRY within a loop. I should point out that alloca has an extra inefficiency vs. the previous approach. It aligns more. So it is using more stack than the other way. And it might pessimize codegen in other ways. The gcc code appears somewhat similar..I think the tables merely describe, again, which function/frame to return to, and that within the frame there is a local integer to determine more precisely what to do. I'm not sure. I saw mention of a switch. ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 13:52:42 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You can't have one jmpbuf per procedure. You need one per TRY scope, > since they can be nested. > > > > On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > Hm. How do I single instance the "EF1"? The current code allocates a > local "EF1" for each try. > I guess, really, it is EF1, EF2, etc. > So there should be a separate local for the jmpbuf pointer, and store > it in each EF* block? > How do I make just one jmpbuf pointer? I couldn't easily figure out how > to in the front end, I need to read it more. > > something like: > > PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > END END END END F1; > => > > void F1() > { > jmp_buf* jb = 0; > EF1 a,b,c; > setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > do stuff 1... > setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > do stuff 2... > setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > do stuff 3... > } > > (The actual syntactic and semantic correctness of this code -- the > existance of the ternary operator, and that it only evaluates one side > or the other, and that assignment is expression..I quite like those > features....) > > > Still, something I can't pin down strikes me as too simple here. > > > If there is just one setjmp, and no integer(s) to keep track of > additional progress, you only ever know the last place you were in a > function. > That doesn't seem adequate. > > > What if a function raises an exception, catches it within itself, and > then raises something else, and then wants to catch that? > It won't know where to resume, right? It's just keep longjmping to the > same place. > > > In the Visual C++ runtime, there is "local unwind" and "global unwind". > "local unwind" is like, "within the same functin", "global unwind" is > across functions. > I think somehow that is related here. > > > e.g. how would you ensure forward progress in this: > > > EXCEPTION E1; > EXCEPTION E2; > EXCEPTION E3; > > > PROCEDURE F4() RAISES ANY = > CONST Function = "F4 "; > BEGIN > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > TRY > Put(Function & Int(Line())); NL(); > RAISE E1; > EXCEPT ELSE > RAISE E2; > END; > EXCEPT ELSE > RAISE E3; > END; > EXCEPT ELSE > END; > END F4; > > > Oddly in my test p251, the stack depth is not increased by TRY. > > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 09:22:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I am OK with what you have currently: > > At each TRY: > > 1. Check if a corresponding alloca block has been allocated by checking > if the corresponding local variable is NIL. > 2. If not, then alloca and save its pointer in the local variable > 3. Execute the try block. > > As you say, alloca should turn into an inline operation using the > compiler's builtin implementation of alloca. > > On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > > Code size will suffer. > > > Indeed. Unoptimized code size does suffer a lot, in functions that use try. > Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > I thought it'd only be one call. I didn't realize our implementation > is as poor as it is, since a better but still > portable implementation doesn't seem too too difficult. > > > Can we maybe do the optimizations I indicate -- no more than one > setjmp/alloca/pushframe per function? > Using a local integer to record the position within the function? > > > Or just give me a week or few to get stack walking working and then > live the regression on other targets? > (NT386 isn't likely to get stack walking, though it *is* certainly > possible; NT does have a decent runtime here..) > > > It *is* nice to not have have the frontend know about jmpbuf size. > > > I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > It doesn't work for intra-function jumps, only inter-function. > > > - Jay > > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 04:52:33 +0000 > > Ah..I'm doing more comparisons of release vs. head...but..I guess your > point is, you'd rather have n locals, which the backend automatically > merges, than n calls to alloca? > It's not a huge difference -- there are still going to be n calls to > setjmp and n calls to pthread_getspecific. > The alloca calls will be dwarfed. > Code size will suffer. > > > And, even so, there are plenty of optimizations to be had, even if > setjmp/pthread_getspecific is used. > > > - It could make a maximum of one call to setjmp/pthread_getspecific > per function > - The calls to alloca could be merged. The frontend could keep track > of how many calls it makes per function, > issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > > So, yes, given my current understanding, it is progress. > The target-dependence is not worth it, imho. > I'll still do some comparisons to release. > > > I'll still be looking into using the gcc unwinder relatively soon. > > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 21:14:17 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > Tony, um..well, um.. first, isn't that how it already worked maybe? > Declaring a new local EF1 for each TRY? It looks like it. > I'll do more testing. > > Yes, it did. I assume you simply have a local variable for each TRY > block that is a pointer now instead of a jmp_buf. Should be OK. > > > So the additional inefficiency is multiplied the same as the rest of > the preexisting inefficiency. > And the preexisting inefficiency is way more than the increase. > > And second, either way, it could be better. > > Basically, the model should be, that if a function has any try or lock, > it calls setjmp once. > And then, it should have one volatile integer, that in a sense > represents the line number. > But not really. It's like, every time you cross a TRY, the integer is > incremented, every time you > cross a finally or unlock, the integer is decremented. Or rather, the > value can be stored. > And then there is a maximum of one one handler per function, it > switches on the integer > to decide where it got into the function and what it should do. > > This is how other compilers work and it is a fairly simple sensible approach. > > - Jay > > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:49:24 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Note that you need a different jmpbuf for each nested TRY! > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > oops, that's not how I thought it worked. I'll do more testing and fix > it -- check for NIL. > > - Jay > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:23:09 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > are allocating on every TRY where previously the storage was statically > allocated. Do you really think this is progress? > > On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > I've back with full keyboard if more explanation needed. The diff is > actually fairly small to read. > I understand it is definitely less efficient, a few more instructions > for every try/lock. > No extra function call, at least with gcc backend. > I haven't tested NT386 yet. Odds are so/so that it works -- the change > is written so that it should work > but I have to test it to be sure, will to roughly tonight. And there > probably is a function call there. > > - Jay > > ________________________________ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 20:44:08 +0000 > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > I only have phone right now. I think it is fairly clear: the jumpbuf in > EF1 is now allocated with alloca, and a pointer stored. It is > definitely a bit less efficient, but the significant advantage is > frontend no longer needs to know the size or alignment of a jumpbuf. > > > As well, there is no longer the problem regarding jumpbuf aligned to > more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > to align to 16 bytes. I don't have an HPUX machine currently to see if > the problem is addressed there. > > > The inefficiency of course can be dramatically mitigated via a stack > walker. I wanted to do this first though, while more targets using > setjmp. > > - Jay/phone > > ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Wed, 5 Jan 2011 13:35:59 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Can you provide a more descriptive checkin comment? I don't know what > has been done here without diving into the diff. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > diff attached > > > Date: Wed, 5 Jan 2011 15:34:55 +0000 > > To: m3commit at elegosoft.com > > From: jkrell at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/05 15:34:55 > > > > Modified files: > > cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > cm3/m3-sys/m3front/src/misc/: Marker.m3 > > cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > > > Log message: > > use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > alloca(Csetjmp__Jumpbuf_size) > > > > to allocate jmp_buf > > > > - eliminates a large swath of target-dependent code > > - allows for covering up the inability to declare > > types with alignment > 64 bits > > > > It is, granted, a little bit slower, in an already prety slow path. > > Note that alloca isn't actually a function call, at least with gcc backend. > > > > > > > > > > > > > > From hosking at cs.purdue.edu Thu Jan 6 20:11:04 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 14:11:04 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> Message-ID: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > I believe you can, but it'd take significant work in the frontend. > The jmpbuf should identify merely which procedure/frame to return to. > There would also be a volatile local integer, that gets altered at certain points through the function. > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > Instead of setjmp, the compiler pessimizes appropriately. > > > So the result is that a function with one or more tries, or one or more locals with destructors, > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > where in the function it is. > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > It is more work through, granted, I can understand that. > And given that we have a much better option for many platforms, the payoff would be reduced. > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > It aligns more. So it is using more stack than the other way. > And it might pessimize codegen in other ways. > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > function/frame to return to, and that within the frame there is a local integer to determine > more precisely what to do. I'm not sure. I saw mention of a switch. > > > - Jay > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 13:52:42 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> You can't have one jmpbuf per procedure. You need one per TRY scope, >> since they can be nested. >> >> >> >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >> >> Hm. How do I single instance the "EF1"? The current code allocates a >> local "EF1" for each try. >> I guess, really, it is EF1, EF2, etc. >> So there should be a separate local for the jmpbuf pointer, and store >> it in each EF* block? >> How do I make just one jmpbuf pointer? I couldn't easily figure out how >> to in the front end, I need to read it more. >> >> something like: >> >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >> END END END END F1; >> => >> >> void F1() >> { >> jmp_buf* jb = 0; >> EF1 a,b,c; >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >> do stuff 1... >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >> do stuff 2... >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >> do stuff 3... >> } >> >> (The actual syntactic and semantic correctness of this code -- the >> existance of the ternary operator, and that it only evaluates one side >> or the other, and that assignment is expression..I quite like those >> features....) >> >> >> Still, something I can't pin down strikes me as too simple here. >> >> >> If there is just one setjmp, and no integer(s) to keep track of >> additional progress, you only ever know the last place you were in a >> function. >> That doesn't seem adequate. >> >> >> What if a function raises an exception, catches it within itself, and >> then raises something else, and then wants to catch that? >> It won't know where to resume, right? It's just keep longjmping to the >> same place. >> >> >> In the Visual C++ runtime, there is "local unwind" and "global unwind". >> "local unwind" is like, "within the same functin", "global unwind" is >> across functions. >> I think somehow that is related here. >> >> >> e.g. how would you ensure forward progress in this: >> >> >> EXCEPTION E1; >> EXCEPTION E2; >> EXCEPTION E3; >> >> >> PROCEDURE F4() RAISES ANY = >> CONST Function = "F4 "; >> BEGIN >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> TRY >> Put(Function & Int(Line())); NL(); >> RAISE E1; >> EXCEPT ELSE >> RAISE E2; >> END; >> EXCEPT ELSE >> RAISE E3; >> END; >> EXCEPT ELSE >> END; >> END F4; >> >> >> Oddly in my test p251, the stack depth is not increased by TRY. >> >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 09:22:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I am OK with what you have currently: >> >> At each TRY: >> >> 1. Check if a corresponding alloca block has been allocated by checking >> if the corresponding local variable is NIL. >> 2. If not, then alloca and save its pointer in the local variable >> 3. Execute the try block. >> >> As you say, alloca should turn into an inline operation using the >> compiler's builtin implementation of alloca. >> >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >> >>> Code size will suffer. >> >> >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >> I thought it'd only be one call. I didn't realize our implementation >> is as poor as it is, since a better but still >> portable implementation doesn't seem too too difficult. >> >> >> Can we maybe do the optimizations I indicate -- no more than one >> setjmp/alloca/pushframe per function? >> Using a local integer to record the position within the function? >> >> >> Or just give me a week or few to get stack walking working and then >> live the regression on other targets? >> (NT386 isn't likely to get stack walking, though it *is* certainly >> possible; NT does have a decent runtime here..) >> >> >> It *is* nice to not have have the frontend know about jmpbuf size. >> >> >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >> It doesn't work for intra-function jumps, only inter-function. >> >> >> - Jay >> >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 04:52:33 +0000 >> >> Ah..I'm doing more comparisons of release vs. head...but..I guess your >> point is, you'd rather have n locals, which the backend automatically >> merges, than n calls to alloca? >> It's not a huge difference -- there are still going to be n calls to >> setjmp and n calls to pthread_getspecific. >> The alloca calls will be dwarfed. >> Code size will suffer. >> >> >> And, even so, there are plenty of optimizations to be had, even if >> setjmp/pthread_getspecific is used. >> >> >> - It could make a maximum of one call to setjmp/pthread_getspecific >> per function >> - The calls to alloca could be merged. The frontend could keep track >> of how many calls it makes per function, >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >> >> >> So, yes, given my current understanding, it is progress. >> The target-dependence is not worth it, imho. >> I'll still do some comparisons to release. >> >> >> I'll still be looking into using the gcc unwinder relatively soon. >> >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 21:14:17 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >> >> Tony, um..well, um.. first, isn't that how it already worked maybe? >> Declaring a new local EF1 for each TRY? It looks like it. >> I'll do more testing. >> >> Yes, it did. I assume you simply have a local variable for each TRY >> block that is a pointer now instead of a jmp_buf. Should be OK. >> >> >> So the additional inefficiency is multiplied the same as the rest of >> the preexisting inefficiency. >> And the preexisting inefficiency is way more than the increase. >> >> And second, either way, it could be better. >> >> Basically, the model should be, that if a function has any try or lock, >> it calls setjmp once. >> And then, it should have one volatile integer, that in a sense >> represents the line number. >> But not really. It's like, every time you cross a TRY, the integer is >> incremented, every time you >> cross a finally or unlock, the integer is decremented. Or rather, the >> value can be stored. >> And then there is a maximum of one one handler per function, it >> switches on the integer >> to decide where it got into the function and what it should do. >> >> This is how other compilers work and it is a fairly simple sensible approach. >> >> - Jay >> >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:49:24 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Note that you need a different jmpbuf for each nested TRY! >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >> >> oops, that's not how I thought it worked. I'll do more testing and fix >> it -- check for NIL. >> >> - Jay >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:23:09 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >> are allocating on every TRY where previously the storage was statically >> allocated. Do you really think this is progress? >> >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >> >> I've back with full keyboard if more explanation needed. The diff is >> actually fairly small to read. >> I understand it is definitely less efficient, a few more instructions >> for every try/lock. >> No extra function call, at least with gcc backend. >> I haven't tested NT386 yet. Odds are so/so that it works -- the change >> is written so that it should work >> but I have to test it to be sure, will to roughly tonight. And there >> probably is a function call there. >> >> - Jay >> >> ________________________________ >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 20:44:08 +0000 >> CC: m3commit at elegosoft.com >> Subject: Re: [M3commit] CVS Update: cm3 >> >> I only have phone right now. I think it is fairly clear: the jumpbuf in >> EF1 is now allocated with alloca, and a pointer stored. It is >> definitely a bit less efficient, but the significant advantage is >> frontend no longer needs to know the size or alignment of a jumpbuf. >> >> >> As well, there is no longer the problem regarding jumpbuf aligned to >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >> to align to 16 bytes. I don't have an HPUX machine currently to see if >> the problem is addressed there. >> >> >> The inefficiency of course can be dramatically mitigated via a stack >> walker. I wanted to do this first though, while more targets using >> setjmp. >> >> - Jay/phone >> >> ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Wed, 5 Jan 2011 13:35:59 -0500 >> CC: jkrell at elego.de; m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Can you provide a more descriptive checkin comment? I don't know what >> has been done here without diving into the diff. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >> >> diff attached >> >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>> To: m3commit at elegosoft.com >>> From: jkrell at elego.de >>> Subject: [M3commit] CVS Update: cm3 >>> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>> >>> Log message: >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>> alloca(Csetjmp__Jumpbuf_size) >>> >>> to allocate jmp_buf >>> >>> - eliminates a large swath of target-dependent code >>> - allows for covering up the inability to declare >>> types with alignment > 64 bits >>> >>> It is, granted, a little bit slower, in an already prety slow path. >>> Note that alloca isn't actually a function call, at least with gcc backend. >>> >> >> >> >> >> >> >> >> >> >> >> >> > From jay.krell at cornell.edu Thu Jan 6 21:33:21 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:33:21 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: Ok. Do you know where to initialize the jmpbuf to NIL? I have a diff that "works" (ie: doesn't crash) and is *close* to correct, it checks for NIL and branches around the alloca for non-NIL, but it also initializes to NIL repeatedly, so no change effectively. ? Index: misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.7 diff -u -w -r1.7 Marker.m3 --- misc/Marker.m3??? 5 Jan 2011 14:34:54 -0000??? 1.7 +++ misc/Marker.m3??? 6 Jan 2011 20:32:00 -0000 @@ -233,6 +233,7 @@ ? ?PROCEDURE CaptureState (frame: CG.Var;? handler: CG.Label) = ?? VAR new: BOOLEAN; +????? label := CG.Next_label (); ?? BEGIN ???? (* int setjmp(void* ); *) ???? IF (setjmp = NIL) THEN @@ -263,18 +264,25 @@ ???????????????????????????????????????? Target.Word.cg_type, 0); ???? END; ???? +??? (* IF frame.jmpbuf = NIL THEN *) + +????? CG.Load_nil (); +????? CG.Load_addr (frame, M3RT.EF1_jmpbuf); +????? CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); + ???? (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) ???? CG.Start_call_direct (alloca, 0, Target.Address.cg_type); ???? CG.Load_int (Target.Word.cg_type, Jumpbuf_size); ???? CG.Pop_param (Target.Word.cg_type); ???? CG.Call_direct (alloca, Target.Address.cg_type); -??? CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -????????????? Target.Address.cg_type); +????? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + +??? (* END *) +??? CG.Set_label (label); ? ???? (* setmp(frame.jmpbuf) *) ???? CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); -??? CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, -???????????? Target.Address.cg_type); +??? CG.Load_addr (frame, M3RT.EF1_jmpbuf); ???? CG.Pop_param (CG.Type.Addr); ???? CG.Call_direct (setjmp, Target.Integer.cg_type); ???? CG.If_true (handler, CG.Never); cvs diff: Diffing stmts Index: stmts/TryFinStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v retrieving revision 1.6 diff -u -w -r1.6 TryFinStmt.m3 --- stmts/TryFinStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.6 +++ stmts/TryFinStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -299,6 +299,10 @@ ???? CG.Load_nil (); ???? CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? l := CG.Next_label (3); ???? CG.Set_label (l, barrier := TRUE); ???? Marker.PushFrame (frame, M3RT.HandlerClass.Finally); Index: stmts/TryStmt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v retrieving revision 1.3 diff -u -w -r1.3 TryStmt.m3 --- stmts/TryStmt.m3??? 5 Jan 2011 14:34:54 -0000??? 1.3 +++ stmts/TryStmt.m3??? 6 Jan 2011 20:32:00 -0000 @@ -10,7 +10,7 @@ ? ?IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; ?IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; -IMPORT Scanner, ESet, Target, M3RT, Tracer; +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; ?FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; ? ?TYPE @@ -411,6 +411,10 @@ ???? CG.Store_addr (frame, M3RT.EF1_exception); ???? ***********************************************) ? +??? (* no jmpbuf yet (avoid repeated alloca in try within loop) *) +??? CG.Load_nil (); +??? CG.Store_addr (frame, M3RT.EF1_jmpbuf); + ???? IF (p.hasElse) THEN ?????? Marker.PushTryElse (l, l+1, frame); ?????? Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); The set_label before one of the PushEFrames could be moved down a bit, to after the NIL initialization, and that'd fix some cases, but I think not all. Thanks, - Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 14:11:04 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > > > > I believe you can, but it'd take significant work in the frontend. > > The jmpbuf should identify merely which procedure/frame to return to. > > There would also be a volatile local integer, that gets altered at certain points through the function. > > When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > Instead of setjmp, the compiler pessimizes appropriately. > > > > > > So the result is that a function with one or more tries, or one or more locals with destructors, > > puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > where in the function it is. > > > > > > If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > > > > > It is more work through, granted, I can understand that. > > And given that we have a much better option for many platforms, the payoff would be reduced. > > > > > > Anyway, I'm trying what you say, like for TRY within a loop. > > > > > > I should point out that alloca has an extra inefficiency vs. the previous approach. > > It aligns more. So it is using more stack than the other way. > > And it might pessimize codegen in other ways. > > > > > > The gcc code appears somewhat similar..I think the tables merely describe, again, which > > function/frame to return to, and that within the frame there is a local integer to determine > > more precisely what to do. I'm not sure. I saw mention of a switch. > > > > > > - Jay > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> You can't have one jmpbuf per procedure. You need one per TRY scope, > >> since they can be nested. > >> > >> > >> > >> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >> > >> Hm. How do I single instance the "EF1"? The current code allocates a > >> local "EF1" for each try. > >> I guess, really, it is EF1, EF2, etc. > >> So there should be a separate local for the jmpbuf pointer, and store > >> it in each EF* block? > >> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >> to in the front end, I need to read it more. > >> > >> something like: > >> > >> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >> END END END END F1; > >> => > >> > >> void F1() > >> { > >> jmp_buf* jb = 0; > >> EF1 a,b,c; > >> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >> do stuff 1... > >> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >> do stuff 2... > >> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >> do stuff 3... > >> } > >> > >> (The actual syntactic and semantic correctness of this code -- the > >> existance of the ternary operator, and that it only evaluates one side > >> or the other, and that assignment is expression..I quite like those > >> features....) > >> > >> > >> Still, something I can't pin down strikes me as too simple here. > >> > >> > >> If there is just one setjmp, and no integer(s) to keep track of > >> additional progress, you only ever know the last place you were in a > >> function. > >> That doesn't seem adequate. > >> > >> > >> What if a function raises an exception, catches it within itself, and > >> then raises something else, and then wants to catch that? > >> It won't know where to resume, right? It's just keep longjmping to the > >> same place. > >> > >> > >> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >> "local unwind" is like, "within the same functin", "global unwind" is > >> across functions. > >> I think somehow that is related here. > >> > >> > >> e.g. how would you ensure forward progress in this: > >> > >> > >> EXCEPTION E1; > >> EXCEPTION E2; > >> EXCEPTION E3; > >> > >> > >> PROCEDURE F4() RAISES ANY = > >> CONST Function = "F4 "; > >> BEGIN > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> TRY > >> Put(Function & Int(Line())); NL(); > >> RAISE E1; > >> EXCEPT ELSE > >> RAISE E2; > >> END; > >> EXCEPT ELSE > >> RAISE E3; > >> END; > >> EXCEPT ELSE > >> END; > >> END F4; > >> > >> > >> Oddly in my test p251, the stack depth is not increased by TRY. > >> > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> I am OK with what you have currently: > >> > >> At each TRY: > >> > >> 1. Check if a corresponding alloca block has been allocated by checking > >> if the corresponding local variable is NIL. > >> 2. If not, then alloca and save its pointer in the local variable > >> 3. Execute the try block. > >> > >> As you say, alloca should turn into an inline operation using the > >> compiler's builtin implementation of alloca. > >> > >> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >> > >>> Code size will suffer. > >> > >> > >> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >> I thought it'd only be one call. I didn't realize our implementation > >> is as poor as it is, since a better but still > >> portable implementation doesn't seem too too difficult. > >> > >> > >> Can we maybe do the optimizations I indicate -- no more than one > >> setjmp/alloca/pushframe per function? > >> Using a local integer to record the position within the function? > >> > >> > >> Or just give me a week or few to get stack walking working and then > >> live the regression on other targets? > >> (NT386 isn't likely to get stack walking, though it *is* certainly > >> possible; NT does have a decent runtime here..) > >> > >> > >> It *is* nice to not have have the frontend know about jmpbuf size. > >> > >> > >> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >> It doesn't work for intra-function jumps, only inter-function. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >> > >> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >> point is, you'd rather have n locals, which the backend automatically > >> merges, than n calls to alloca? > >> It's not a huge difference -- there are still going to be n calls to > >> setjmp and n calls to pthread_getspecific. > >> The alloca calls will be dwarfed. > >> Code size will suffer. > >> > >> > >> And, even so, there are plenty of optimizations to be had, even if > >> setjmp/pthread_getspecific is used. > >> > >> > >> - It could make a maximum of one call to setjmp/pthread_getspecific > >> per function > >> - The calls to alloca could be merged. The frontend could keep track > >> of how many calls it makes per function, > >> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >> > >> > >> So, yes, given my current understanding, it is progress. > >> The target-dependence is not worth it, imho. > >> I'll still do some comparisons to release. > >> > >> > >> I'll still be looking into using the gcc unwinder relatively soon. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >> > >> Tony, um..well, um.. first, isn't that how it already worked maybe? > >> Declaring a new local EF1 for each TRY? It looks like it. > >> I'll do more testing. > >> > >> Yes, it did. I assume you simply have a local variable for each TRY > >> block that is a pointer now instead of a jmp_buf. Should be OK. > >> > >> > >> So the additional inefficiency is multiplied the same as the rest of > >> the preexisting inefficiency. > >> And the preexisting inefficiency is way more than the increase. > >> > >> And second, either way, it could be better. > >> > >> Basically, the model should be, that if a function has any try or lock, > >> it calls setjmp once. > >> And then, it should have one volatile integer, that in a sense > >> represents the line number. > >> But not really. It's like, every time you cross a TRY, the integer is > >> incremented, every time you > >> cross a finally or unlock, the integer is decremented. Or rather, the > >> value can be stored. > >> And then there is a maximum of one one handler per function, it > >> switches on the integer > >> to decide where it got into the function and what it should do. > >> > >> This is how other compilers work and it is a fairly simple sensible approach. > >> > >> - Jay > >> > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Note that you need a different jmpbuf for each nested TRY! > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >> > >> oops, that's not how I thought it worked. I'll do more testing and fix > >> it -- check for NIL. > >> > >> - Jay > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >> are allocating on every TRY where previously the storage was statically > >> allocated. Do you really think this is progress? > >> > >> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >> > >> I've back with full keyboard if more explanation needed. The diff is > >> actually fairly small to read. > >> I understand it is definitely less efficient, a few more instructions > >> for every try/lock. > >> No extra function call, at least with gcc backend. > >> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >> is written so that it should work > >> but I have to test it to be sure, will to roughly tonight. And there > >> probably is a function call there. > >> > >> - Jay > >> > >> ________________________________ > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >> CC: m3commit at elegosoft.com > >> Subject: Re: [M3commit] CVS Update: cm3 > >> > >> I only have phone right now. I think it is fairly clear: the jumpbuf in > >> EF1 is now allocated with alloca, and a pointer stored. It is > >> definitely a bit less efficient, but the significant advantage is > >> frontend no longer needs to know the size or alignment of a jumpbuf. > >> > >> > >> As well, there is no longer the problem regarding jumpbuf aligned to > >> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >> to align to 16 bytes. I don't have an HPUX machine currently to see if > >> the problem is addressed there. > >> > >> > >> The inefficiency of course can be dramatically mitigated via a stack > >> walker. I wanted to do this first though, while more targets using > >> setjmp. > >> > >> - Jay/phone > >> > >> ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Can you provide a more descriptive checkin comment? I don't know what > >> has been done here without diving into the diff. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >> > >> diff attached > >> > >>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>> To: m3commit at elegosoft.com > >>> From: jkrell at elego.de > >>> Subject: [M3commit] CVS Update: cm3 > >>> > >>> CVSROOT: /usr/cvs > >>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>> > >>> Modified files: > >>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>> > >>> Log message: > >>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>> alloca(Csetjmp__Jumpbuf_size) > >>> > >>> to allocate jmp_buf > >>> > >>> - eliminates a large swath of target-dependent code > >>> - allows for covering up the inability to declare > >>> types with alignment > 64 bits > >>> > >>> It is, granted, a little bit slower, in an already prety slow path. > >>> Note that alloca isn't actually a function call, at least with gcc backend. > >>> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > > > From jkrell at elego.de Thu Jan 6 21:40:16 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 6 Jan 2011 21:40:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110106204016.8C4BF2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/06 21:40:16 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 Log message: use convenience Load/Store_addr instead of Load/Store From hosking at cs.purdue.edu Thu Jan 6 21:42:33 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:42:33 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> Message-ID: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> I don't understand what you mean by "initializes to NIL". How are you creating the frame variable? If you do it properly the language semantics will cause it be initialized to NIL automatically. On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > Ok. > Do you know where to initialize the jmpbuf to NIL? > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > it checks for NIL and branches around the alloca for non-NIL, but it > also initializes to NIL repeatedly, so no change effectively. > > > Index: misc/Marker.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > retrieving revision 1.7 > diff -u -w -r1.7 Marker.m3 > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > @@ -233,6 +233,7 @@ > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > VAR new: BOOLEAN; > + label := CG.Next_label (); > BEGIN > (* int setjmp(void* ); *) > IF (setjmp = NIL) THEN > @@ -263,18 +264,25 @@ > Target.Word.cg_type, 0); > END; > > + (* IF frame.jmpbuf = NIL THEN *) > + > + CG.Load_nil (); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > + > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > CG.Pop_param (Target.Word.cg_type); > CG.Call_direct (alloca, Target.Address.cg_type); > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > + (* END *) > + CG.Set_label (label); > > (* setmp(frame.jmpbuf) *) > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > - Target.Address.cg_type); > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > CG.Pop_param (CG.Type.Addr); > CG.Call_direct (setjmp, Target.Integer.cg_type); > CG.If_true (handler, CG.Never); > cvs diff: Diffing stmts > Index: stmts/TryFinStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > retrieving revision 1.6 > diff -u -w -r1.6 TryFinStmt.m3 > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -299,6 +299,10 @@ > CG.Load_nil (); > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > l := CG.Next_label (3); > CG.Set_label (l, barrier := TRUE); > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > Index: stmts/TryStmt.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > retrieving revision 1.3 > diff -u -w -r1.3 TryStmt.m3 > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > @@ -10,7 +10,7 @@ > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > TYPE > @@ -411,6 +411,10 @@ > CG.Store_addr (frame, M3RT.EF1_exception); > ***********************************************) > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > + CG.Load_nil (); > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > + > IF (p.hasElse) THEN > Marker.PushTryElse (l, l+1, frame); > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > The set_label before one of the PushEFrames could be moved down a bit, > to after the NIL initialization, and that'd fix some cases, but I think not all. > > Thanks, > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 14:11:04 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >> >>> >>> I believe you can, but it'd take significant work in the frontend. >>> The jmpbuf should identify merely which procedure/frame to return to. >>> There would also be a volatile local integer, that gets altered at certain points through the function. >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>> Instead of setjmp, the compiler pessimizes appropriately. >>> >>> >>> So the result is that a function with one or more tries, or one or more locals with destructors, >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>> where in the function it is. >>> >>> >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>> >>> >>> It is more work through, granted, I can understand that. >>> And given that we have a much better option for many platforms, the payoff would be reduced. >>> >>> >>> Anyway, I'm trying what you say, like for TRY within a loop. >>> >>> >>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>> It aligns more. So it is using more stack than the other way. >>> And it might pessimize codegen in other ways. >>> >>> >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>> function/frame to return to, and that within the frame there is a local integer to determine >>> more precisely what to do. I'm not sure. I saw mention of a switch. >>> >>> >>> - Jay >>> >>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>> since they can be nested. >>>> >>>> >>>> >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>> >>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>> local "EF1" for each try. >>>> I guess, really, it is EF1, EF2, etc. >>>> So there should be a separate local for the jmpbuf pointer, and store >>>> it in each EF* block? >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>> to in the front end, I need to read it more. >>>> >>>> something like: >>>> >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>> END END END END F1; >>>> => >>>> >>>> void F1() >>>> { >>>> jmp_buf* jb = 0; >>>> EF1 a,b,c; >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>> do stuff 1... >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>> do stuff 2... >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>> do stuff 3... >>>> } >>>> >>>> (The actual syntactic and semantic correctness of this code -- the >>>> existance of the ternary operator, and that it only evaluates one side >>>> or the other, and that assignment is expression..I quite like those >>>> features....) >>>> >>>> >>>> Still, something I can't pin down strikes me as too simple here. >>>> >>>> >>>> If there is just one setjmp, and no integer(s) to keep track of >>>> additional progress, you only ever know the last place you were in a >>>> function. >>>> That doesn't seem adequate. >>>> >>>> >>>> What if a function raises an exception, catches it within itself, and >>>> then raises something else, and then wants to catch that? >>>> It won't know where to resume, right? It's just keep longjmping to the >>>> same place. >>>> >>>> >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>> "local unwind" is like, "within the same functin", "global unwind" is >>>> across functions. >>>> I think somehow that is related here. >>>> >>>> >>>> e.g. how would you ensure forward progress in this: >>>> >>>> >>>> EXCEPTION E1; >>>> EXCEPTION E2; >>>> EXCEPTION E3; >>>> >>>> >>>> PROCEDURE F4() RAISES ANY = >>>> CONST Function = "F4 "; >>>> BEGIN >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> TRY >>>> Put(Function & Int(Line())); NL(); >>>> RAISE E1; >>>> EXCEPT ELSE >>>> RAISE E2; >>>> END; >>>> EXCEPT ELSE >>>> RAISE E3; >>>> END; >>>> EXCEPT ELSE >>>> END; >>>> END F4; >>>> >>>> >>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>> >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> I am OK with what you have currently: >>>> >>>> At each TRY: >>>> >>>> 1. Check if a corresponding alloca block has been allocated by checking >>>> if the corresponding local variable is NIL. >>>> 2. If not, then alloca and save its pointer in the local variable >>>> 3. Execute the try block. >>>> >>>> As you say, alloca should turn into an inline operation using the >>>> compiler's builtin implementation of alloca. >>>> >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>> >>>>> Code size will suffer. >>>> >>>> >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>> I thought it'd only be one call. I didn't realize our implementation >>>> is as poor as it is, since a better but still >>>> portable implementation doesn't seem too too difficult. >>>> >>>> >>>> Can we maybe do the optimizations I indicate -- no more than one >>>> setjmp/alloca/pushframe per function? >>>> Using a local integer to record the position within the function? >>>> >>>> >>>> Or just give me a week or few to get stack walking working and then >>>> live the regression on other targets? >>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>> possible; NT does have a decent runtime here..) >>>> >>>> >>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>> >>>> >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>> It doesn't work for intra-function jumps, only inter-function. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>> >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>> point is, you'd rather have n locals, which the backend automatically >>>> merges, than n calls to alloca? >>>> It's not a huge difference -- there are still going to be n calls to >>>> setjmp and n calls to pthread_getspecific. >>>> The alloca calls will be dwarfed. >>>> Code size will suffer. >>>> >>>> >>>> And, even so, there are plenty of optimizations to be had, even if >>>> setjmp/pthread_getspecific is used. >>>> >>>> >>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>> per function >>>> - The calls to alloca could be merged. The frontend could keep track >>>> of how many calls it makes per function, >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>> >>>> >>>> So, yes, given my current understanding, it is progress. >>>> The target-dependence is not worth it, imho. >>>> I'll still do some comparisons to release. >>>> >>>> >>>> I'll still be looking into using the gcc unwinder relatively soon. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>> >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>> Declaring a new local EF1 for each TRY? It looks like it. >>>> I'll do more testing. >>>> >>>> Yes, it did. I assume you simply have a local variable for each TRY >>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>> >>>> >>>> So the additional inefficiency is multiplied the same as the rest of >>>> the preexisting inefficiency. >>>> And the preexisting inefficiency is way more than the increase. >>>> >>>> And second, either way, it could be better. >>>> >>>> Basically, the model should be, that if a function has any try or lock, >>>> it calls setjmp once. >>>> And then, it should have one volatile integer, that in a sense >>>> represents the line number. >>>> But not really. It's like, every time you cross a TRY, the integer is >>>> incremented, every time you >>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>> value can be stored. >>>> And then there is a maximum of one one handler per function, it >>>> switches on the integer >>>> to decide where it got into the function and what it should do. >>>> >>>> This is how other compilers work and it is a fairly simple sensible approach. >>>> >>>> - Jay >>>> >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Note that you need a different jmpbuf for each nested TRY! >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>> >>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>> it -- check for NIL. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>> are allocating on every TRY where previously the storage was statically >>>> allocated. Do you really think this is progress? >>>> >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>> >>>> I've back with full keyboard if more explanation needed. The diff is >>>> actually fairly small to read. >>>> I understand it is definitely less efficient, a few more instructions >>>> for every try/lock. >>>> No extra function call, at least with gcc backend. >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>> is written so that it should work >>>> but I have to test it to be sure, will to roughly tonight. And there >>>> probably is a function call there. >>>> >>>> - Jay >>>> >>>> ________________________________ >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>> CC: m3commit at elegosoft.com >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>> definitely a bit less efficient, but the significant advantage is >>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>> >>>> >>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>> the problem is addressed there. >>>> >>>> >>>> The inefficiency of course can be dramatically mitigated via a stack >>>> walker. I wanted to do this first though, while more targets using >>>> setjmp. >>>> >>>> - Jay/phone >>>> >>>> ________________________________ >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> Can you provide a more descriptive checkin comment? I don't know what >>>> has been done here without diving into the diff. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>> >>>> diff attached >>>> >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>> To: m3commit at elegosoft.com >>>>> From: jkrell at elego.de >>>>> Subject: [M3commit] CVS Update: cm3 >>>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>> >>>>> Log message: >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>> alloca(Csetjmp__Jumpbuf_size) >>>>> >>>>> to allocate jmp_buf >>>>> >>>>> - eliminates a large swath of target-dependent code >>>>> - allows for covering up the inability to declare >>>>> types with alignment > 64 bits >>>>> >>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 21:48:56 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:48:56 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: The same way as before. I think this operates at too low a level to get any automatic initialization. TryStmt.m3 and TryFinStmt.m3: ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); I agree though, this might not be ideal. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 15:42:33 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > I don't understand what you mean by "initializes to NIL". > How are you creating the frame variable? > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > Ok. > > Do you know where to initialize the jmpbuf to NIL? > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > it checks for NIL and branches around the alloca for non-NIL, but it > > also initializes to NIL repeatedly, so no change effectively. > > > > > > Index: misc/Marker.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > retrieving revision 1.7 > > diff -u -w -r1.7 Marker.m3 > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > @@ -233,6 +233,7 @@ > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > VAR new: BOOLEAN; > > + label := CG.Next_label (); > > BEGIN > > (* int setjmp(void* ); *) > > IF (setjmp = NIL) THEN > > @@ -263,18 +264,25 @@ > > Target.Word.cg_type, 0); > > END; > > > > + (* IF frame.jmpbuf = NIL THEN *) > > + > > + CG.Load_nil (); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > + > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > CG.Pop_param (Target.Word.cg_type); > > CG.Call_direct (alloca, Target.Address.cg_type); > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > + (* END *) > > + CG.Set_label (label); > > > > (* setmp(frame.jmpbuf) *) > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > - Target.Address.cg_type); > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > CG.Pop_param (CG.Type.Addr); > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > CG.If_true (handler, CG.Never); > > cvs diff: Diffing stmts > > Index: stmts/TryFinStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > retrieving revision 1.6 > > diff -u -w -r1.6 TryFinStmt.m3 > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -299,6 +299,10 @@ > > CG.Load_nil (); > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > l := CG.Next_label (3); > > CG.Set_label (l, barrier := TRUE); > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > Index: stmts/TryStmt.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > retrieving revision 1.3 > > diff -u -w -r1.3 TryStmt.m3 > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > @@ -10,7 +10,7 @@ > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > TYPE > > @@ -411,6 +411,10 @@ > > CG.Store_addr (frame, M3RT.EF1_exception); > > ***********************************************) > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > + CG.Load_nil (); > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > + > > IF (p.hasElse) THEN > > Marker.PushTryElse (l, l+1, frame); > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > Thanks, > > - Jay > > > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >> > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > >> 305 N. University Street | West Lafayette | IN 47907 | USA > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >> > >> > >> > >> > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >> > >>> > >>> I believe you can, but it'd take significant work in the frontend. > >>> The jmpbuf should identify merely which procedure/frame to return to. > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>> Instead of setjmp, the compiler pessimizes appropriately. > >>> > >>> > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>> where in the function it is. > >>> > >>> > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>> > >>> > >>> It is more work through, granted, I can understand that. > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>> > >>> > >>> Anyway, I'm trying what you say, like for TRY within a loop. > >>> > >>> > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>> It aligns more. So it is using more stack than the other way. > >>> And it might pessimize codegen in other ways. > >>> > >>> > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>> function/frame to return to, and that within the frame there is a local integer to determine > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>> > >>> > >>> - Jay > >>> > >>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>> since they can be nested. > >>>> > >>>> > >>>> > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>> > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>> local "EF1" for each try. > >>>> I guess, really, it is EF1, EF2, etc. > >>>> So there should be a separate local for the jmpbuf pointer, and store > >>>> it in each EF* block? > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>> to in the front end, I need to read it more. > >>>> > >>>> something like: > >>>> > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>> END END END END F1; > >>>> => > >>>> > >>>> void F1() > >>>> { > >>>> jmp_buf* jb = 0; > >>>> EF1 a,b,c; > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>> do stuff 1... > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>> do stuff 2... > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>> do stuff 3... > >>>> } > >>>> > >>>> (The actual syntactic and semantic correctness of this code -- the > >>>> existance of the ternary operator, and that it only evaluates one side > >>>> or the other, and that assignment is expression..I quite like those > >>>> features....) > >>>> > >>>> > >>>> Still, something I can't pin down strikes me as too simple here. > >>>> > >>>> > >>>> If there is just one setjmp, and no integer(s) to keep track of > >>>> additional progress, you only ever know the last place you were in a > >>>> function. > >>>> That doesn't seem adequate. > >>>> > >>>> > >>>> What if a function raises an exception, catches it within itself, and > >>>> then raises something else, and then wants to catch that? > >>>> It won't know where to resume, right? It's just keep longjmping to the > >>>> same place. > >>>> > >>>> > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>> across functions. > >>>> I think somehow that is related here. > >>>> > >>>> > >>>> e.g. how would you ensure forward progress in this: > >>>> > >>>> > >>>> EXCEPTION E1; > >>>> EXCEPTION E2; > >>>> EXCEPTION E3; > >>>> > >>>> > >>>> PROCEDURE F4() RAISES ANY = > >>>> CONST Function = "F4 "; > >>>> BEGIN > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> TRY > >>>> Put(Function & Int(Line())); NL(); > >>>> RAISE E1; > >>>> EXCEPT ELSE > >>>> RAISE E2; > >>>> END; > >>>> EXCEPT ELSE > >>>> RAISE E3; > >>>> END; > >>>> EXCEPT ELSE > >>>> END; > >>>> END F4; > >>>> > >>>> > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> I am OK with what you have currently: > >>>> > >>>> At each TRY: > >>>> > >>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>> if the corresponding local variable is NIL. > >>>> 2. If not, then alloca and save its pointer in the local variable > >>>> 3. Execute the try block. > >>>> > >>>> As you say, alloca should turn into an inline operation using the > >>>> compiler's builtin implementation of alloca. > >>>> > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>> > >>>>> Code size will suffer. > >>>> > >>>> > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>> I thought it'd only be one call. I didn't realize our implementation > >>>> is as poor as it is, since a better but still > >>>> portable implementation doesn't seem too too difficult. > >>>> > >>>> > >>>> Can we maybe do the optimizations I indicate -- no more than one > >>>> setjmp/alloca/pushframe per function? > >>>> Using a local integer to record the position within the function? > >>>> > >>>> > >>>> Or just give me a week or few to get stack walking working and then > >>>> live the regression on other targets? > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>> possible; NT does have a decent runtime here..) > >>>> > >>>> > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>> > >>>> > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>> It doesn't work for intra-function jumps, only inter-function. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>> > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>> point is, you'd rather have n locals, which the backend automatically > >>>> merges, than n calls to alloca? > >>>> It's not a huge difference -- there are still going to be n calls to > >>>> setjmp and n calls to pthread_getspecific. > >>>> The alloca calls will be dwarfed. > >>>> Code size will suffer. > >>>> > >>>> > >>>> And, even so, there are plenty of optimizations to be had, even if > >>>> setjmp/pthread_getspecific is used. > >>>> > >>>> > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>> per function > >>>> - The calls to alloca could be merged. The frontend could keep track > >>>> of how many calls it makes per function, > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>> > >>>> > >>>> So, yes, given my current understanding, it is progress. > >>>> The target-dependence is not worth it, imho. > >>>> I'll still do some comparisons to release. > >>>> > >>>> > >>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>> > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>> > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>> I'll do more testing. > >>>> > >>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>> > >>>> > >>>> So the additional inefficiency is multiplied the same as the rest of > >>>> the preexisting inefficiency. > >>>> And the preexisting inefficiency is way more than the increase. > >>>> > >>>> And second, either way, it could be better. > >>>> > >>>> Basically, the model should be, that if a function has any try or lock, > >>>> it calls setjmp once. > >>>> And then, it should have one volatile integer, that in a sense > >>>> represents the line number. > >>>> But not really. It's like, every time you cross a TRY, the integer is > >>>> incremented, every time you > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>> value can be stored. > >>>> And then there is a maximum of one one handler per function, it > >>>> switches on the integer > >>>> to decide where it got into the function and what it should do. > >>>> > >>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Note that you need a different jmpbuf for each nested TRY! > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>> > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>> it -- check for NIL. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>> CC: m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>> are allocating on every TRY where previously the storage was statically > >>>> allocated. Do you really think this is progress? > >>>> > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>> > >>>> I've back with full keyboard if more explanation needed. The diff is > >>>> actually fairly small to read. > >>>> I understand it is definitely less efficient, a few more instructions > >>>> for every try/lock. > >>>> No extra function call, at least with gcc backend. > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>> is written so that it should work > >>>> but I have to test it to be sure, will to roughly tonight. And there > >>>> probably is a function call there. > >>>> > >>>> - Jay > >>>> > >>>> ________________________________ > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>> CC: m3commit at elegosoft.com > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>> definitely a bit less efficient, but the significant advantage is > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>> > >>>> > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>> the problem is addressed there. > >>>> > >>>> > >>>> The inefficiency of course can be dramatically mitigated via a stack > >>>> walker. I wanted to do this first though, while more targets using > >>>> setjmp. > >>>> > >>>> - Jay/phone > >>>> > >>>> ________________________________ > >>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>> From: hosking at cs.purdue.edu > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>> To: jay.krell at cornell.edu > >>>> > >>>> Can you provide a more descriptive checkin comment? I don't know what > >>>> has been done here without diving into the diff. > >>>> > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>> > >>>> > >>>> > >>>> > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>> > >>>> diff attached > >>>> > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>> To: m3commit at elegosoft.com > >>>>> From: jkrell at elego.de > >>>>> Subject: [M3commit] CVS Update: cm3 > >>>>> > >>>>> CVSROOT: /usr/cvs > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>> > >>>>> Modified files: > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>> > >>>>> Log message: > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>> > >>>>> to allocate jmp_buf > >>>>> > >>>>> - eliminates a large swath of target-dependent code > >>>>> - allows for covering up the inability to declare > >>>>> types with alignment > 64 bits > >>>>> > >>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>> > >> > > > From jay.krell at cornell.edu Thu Jan 6 21:51:58 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 20:51:58 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: ps: I think there other non-ideal initializations here. e.g. TryFinStmt.m3:Compile2 ??? (* declare and initialize the info record *) ??? frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, ?????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ?????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_procedure (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_handler); ??? CG.Load_static_link (p.handler.cg_proc); ??? CG.Store_addr (frame, M3RT.EF2_frame); Putting TRY/LOCK in loops probably repeatedly does the same initializations. Granted, this is non-stack-walker code. Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. ?- Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3commit at elegosoft.com > Subject: RE: [M3commit] CVS Update: cm3 > Date: Thu, 6 Jan 2011 20:48:56 +0000 > > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 15:42:33 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > I don't understand what you mean by "initializes to NIL". > > How are you creating the frame variable? > > If you do it properly the language semantics will cause it be initialized to NIL automatically. > > > > On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > > > > > > > Ok. > > > Do you know where to initialize the jmpbuf to NIL? > > > > > > I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > > it checks for NIL and branches around the alloca for non-NIL, but it > > > also initializes to NIL repeatedly, so no change effectively. > > > > > > > > > Index: misc/Marker.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > > retrieving revision 1.7 > > > diff -u -w -r1.7 Marker.m3 > > > --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > > +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -233,6 +233,7 @@ > > > > > > PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > > VAR new: BOOLEAN; > > > + label := CG.Next_label (); > > > BEGIN > > > (* int setjmp(void* ); *) > > > IF (setjmp = NIL) THEN > > > @@ -263,18 +264,25 @@ > > > Target.Word.cg_type, 0); > > > END; > > > > > > + (* IF frame.jmpbuf = NIL THEN *) > > > + > > > + CG.Load_nil (); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > > + > > > (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > > CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > > CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > > CG.Pop_param (Target.Word.cg_type); > > > CG.Call_direct (alloca, Target.Address.cg_type); > > > - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > + (* END *) > > > + CG.Set_label (label); > > > > > > (* setmp(frame.jmpbuf) *) > > > CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > > - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > > - Target.Address.cg_type); > > > + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > > CG.Pop_param (CG.Type.Addr); > > > CG.Call_direct (setjmp, Target.Integer.cg_type); > > > CG.If_true (handler, CG.Never); > > > cvs diff: Diffing stmts > > > Index: stmts/TryFinStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > > retrieving revision 1.6 > > > diff -u -w -r1.6 TryFinStmt.m3 > > > --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > > +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -299,6 +299,10 @@ > > > CG.Load_nil (); > > > CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > l := CG.Next_label (3); > > > CG.Set_label (l, barrier := TRUE); > > > Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > > Index: stmts/TryStmt.m3 > > > =================================================================== > > > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > > retrieving revision 1.3 > > > diff -u -w -r1.3 TryStmt.m3 > > > --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > > +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > > @@ -10,7 +10,7 @@ > > > > > > IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > > IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > > -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > > +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > > FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > > > > > TYPE > > > @@ -411,6 +411,10 @@ > > > CG.Store_addr (frame, M3RT.EF1_exception); > > > ***********************************************) > > > > > > + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > > + CG.Load_nil (); > > > + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > > + > > > IF (p.hasElse) THEN > > > Marker.PushTryElse (l, l+1, frame); > > > Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > > > > > > > > The set_label before one of the PushEFrames could be moved down a bit, > > > to after the NIL initialization, and that'd fix some cases, but I think not all. > > > > > > Thanks, > > > - Jay > > > > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >> > > >> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >> 305 N. University Street | West Lafayette | IN 47907 | USA > > >> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >> > > >> > > >> > > >> > > >> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >> > > >>> > > >>> I believe you can, but it'd take significant work in the frontend. > > >>> The jmpbuf should identify merely which procedure/frame to return to. > > >>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>> Instead of setjmp, the compiler pessimizes appropriately. > > >>> > > >>> > > >>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>> where in the function it is. > > >>> > > >>> > > >>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>> > > >>> > > >>> It is more work through, granted, I can understand that. > > >>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>> > > >>> > > >>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>> > > >>> > > >>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>> It aligns more. So it is using more stack than the other way. > > >>> And it might pessimize codegen in other ways. > > >>> > > >>> > > >>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>> function/frame to return to, and that within the frame there is a local integer to determine > > >>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>> > > >>> > > >>> - Jay > > >>> > > >>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>> since they can be nested. > > >>>> > > >>>> > > >>>> > > >>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>> > > >>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>> local "EF1" for each try. > > >>>> I guess, really, it is EF1, EF2, etc. > > >>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>> it in each EF* block? > > >>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>> to in the front end, I need to read it more. > > >>>> > > >>>> something like: > > >>>> > > >>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>> END END END END F1; > > >>>> => > > >>>> > > >>>> void F1() > > >>>> { > > >>>> jmp_buf* jb = 0; > > >>>> EF1 a,b,c; > > >>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>> do stuff 1... > > >>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>> do stuff 2... > > >>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>> do stuff 3... > > >>>> } > > >>>> > > >>>> (The actual syntactic and semantic correctness of this code -- the > > >>>> existance of the ternary operator, and that it only evaluates one side > > >>>> or the other, and that assignment is expression..I quite like those > > >>>> features....) > > >>>> > > >>>> > > >>>> Still, something I can't pin down strikes me as too simple here. > > >>>> > > >>>> > > >>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>> additional progress, you only ever know the last place you were in a > > >>>> function. > > >>>> That doesn't seem adequate. > > >>>> > > >>>> > > >>>> What if a function raises an exception, catches it within itself, and > > >>>> then raises something else, and then wants to catch that? > > >>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>> same place. > > >>>> > > >>>> > > >>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>> across functions. > > >>>> I think somehow that is related here. > > >>>> > > >>>> > > >>>> e.g. how would you ensure forward progress in this: > > >>>> > > >>>> > > >>>> EXCEPTION E1; > > >>>> EXCEPTION E2; > > >>>> EXCEPTION E3; > > >>>> > > >>>> > > >>>> PROCEDURE F4() RAISES ANY = > > >>>> CONST Function = "F4 "; > > >>>> BEGIN > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> TRY > > >>>> Put(Function & Int(Line())); NL(); > > >>>> RAISE E1; > > >>>> EXCEPT ELSE > > >>>> RAISE E2; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> RAISE E3; > > >>>> END; > > >>>> EXCEPT ELSE > > >>>> END; > > >>>> END F4; > > >>>> > > >>>> > > >>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> I am OK with what you have currently: > > >>>> > > >>>> At each TRY: > > >>>> > > >>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>> if the corresponding local variable is NIL. > > >>>> 2. If not, then alloca and save its pointer in the local variable > > >>>> 3. Execute the try block. > > >>>> > > >>>> As you say, alloca should turn into an inline operation using the > > >>>> compiler's builtin implementation of alloca. > > >>>> > > >>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>> > > >>>>> Code size will suffer. > > >>>> > > >>>> > > >>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>> I thought it'd only be one call. I didn't realize our implementation > > >>>> is as poor as it is, since a better but still > > >>>> portable implementation doesn't seem too too difficult. > > >>>> > > >>>> > > >>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>> setjmp/alloca/pushframe per function? > > >>>> Using a local integer to record the position within the function? > > >>>> > > >>>> > > >>>> Or just give me a week or few to get stack walking working and then > > >>>> live the regression on other targets? > > >>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>> possible; NT does have a decent runtime here..) > > >>>> > > >>>> > > >>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>> > > >>>> > > >>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>> It doesn't work for intra-function jumps, only inter-function. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>> > > >>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>> point is, you'd rather have n locals, which the backend automatically > > >>>> merges, than n calls to alloca? > > >>>> It's not a huge difference -- there are still going to be n calls to > > >>>> setjmp and n calls to pthread_getspecific. > > >>>> The alloca calls will be dwarfed. > > >>>> Code size will suffer. > > >>>> > > >>>> > > >>>> And, even so, there are plenty of optimizations to be had, even if > > >>>> setjmp/pthread_getspecific is used. > > >>>> > > >>>> > > >>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>> per function > > >>>> - The calls to alloca could be merged. The frontend could keep track > > >>>> of how many calls it makes per function, > > >>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>> > > >>>> > > >>>> So, yes, given my current understanding, it is progress. > > >>>> The target-dependence is not worth it, imho. > > >>>> I'll still do some comparisons to release. > > >>>> > > >>>> > > >>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>> > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>> > > >>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>> I'll do more testing. > > >>>> > > >>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>> > > >>>> > > >>>> So the additional inefficiency is multiplied the same as the rest of > > >>>> the preexisting inefficiency. > > >>>> And the preexisting inefficiency is way more than the increase. > > >>>> > > >>>> And second, either way, it could be better. > > >>>> > > >>>> Basically, the model should be, that if a function has any try or lock, > > >>>> it calls setjmp once. > > >>>> And then, it should have one volatile integer, that in a sense > > >>>> represents the line number. > > >>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>> incremented, every time you > > >>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>> value can be stored. > > >>>> And then there is a maximum of one one handler per function, it > > >>>> switches on the integer > > >>>> to decide where it got into the function and what it should do. > > >>>> > > >>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Note that you need a different jmpbuf for each nested TRY! > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>> > > >>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>> it -- check for NIL. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>> CC: m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>> are allocating on every TRY where previously the storage was statically > > >>>> allocated. Do you really think this is progress? > > >>>> > > >>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>> > > >>>> I've back with full keyboard if more explanation needed. The diff is > > >>>> actually fairly small to read. > > >>>> I understand it is definitely less efficient, a few more instructions > > >>>> for every try/lock. > > >>>> No extra function call, at least with gcc backend. > > >>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>> is written so that it should work > > >>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>> probably is a function call there. > > >>>> > > >>>> - Jay > > >>>> > > >>>> ________________________________ > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> > > >>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>> definitely a bit less efficient, but the significant advantage is > > >>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>> > > >>>> > > >>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>> the problem is addressed there. > > >>>> > > >>>> > > >>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>> walker. I wanted to do this first though, while more targets using > > >>>> setjmp. > > >>>> > > >>>> - Jay/phone > > >>>> > > >>>> ________________________________ > > >>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>> From: hosking at cs.purdue.edu > > >>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>> To: jay.krell at cornell.edu > > >>>> > > >>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>> has been done here without diving into the diff. > > >>>> > > >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>> > > >>>> diff attached > > >>>> > > >>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>> To: m3commit at elegosoft.com > > >>>>> From: jkrell at elego.de > > >>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>> > > >>>>> CVSROOT: /usr/cvs > > >>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>> > > >>>>> Modified files: > > >>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>> > > >>>>> Log message: > > >>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>> > > >>>>> to allocate jmp_buf > > >>>>> > > >>>>> - eliminates a large swath of target-dependent code > > >>>>> - allows for covering up the inability to declare > > >>>>> types with alignment > 64 bits > > >>>>> > > >>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Thu Jan 6 21:58:54 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 15:58:54 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu> , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu> , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu> , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu> Message-ID: What you want to do is use the "variable" slot in the frame to hold a variable for TRY frames, similarly to PROC frames. Then it will be initialized correctly. You should give it type Addr.T. On Jan 6, 2011, at 3:48 PM, Jay K wrote: > > The same way as before. I think this operates at too low a level to get any automatic initialization. > > TryStmt.m3 and TryFinStmt.m3: > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > > I agree though, this might not be ideal. > > - Jay > > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 15:42:33 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> I don't understand what you mean by "initializes to NIL". >> How are you creating the frame variable? >> If you do it properly the language semantics will cause it be initialized to NIL automatically. >> >> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >> >>> >>> Ok. >>> Do you know where to initialize the jmpbuf to NIL? >>> >>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>> it checks for NIL and branches around the alloca for non-NIL, but it >>> also initializes to NIL repeatedly, so no change effectively. >>> >>> >>> Index: misc/Marker.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>> retrieving revision 1.7 >>> diff -u -w -r1.7 Marker.m3 >>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -233,6 +233,7 @@ >>> >>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>> VAR new: BOOLEAN; >>> + label := CG.Next_label (); >>> BEGIN >>> (* int setjmp(void* ); *) >>> IF (setjmp = NIL) THEN >>> @@ -263,18 +264,25 @@ >>> Target.Word.cg_type, 0); >>> END; >>> >>> + (* IF frame.jmpbuf = NIL THEN *) >>> + >>> + CG.Load_nil (); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>> + >>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>> CG.Pop_param (Target.Word.cg_type); >>> CG.Call_direct (alloca, Target.Address.cg_type); >>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> + (* END *) >>> + CG.Set_label (label); >>> >>> (* setmp(frame.jmpbuf) *) >>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>> - Target.Address.cg_type); >>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>> CG.Pop_param (CG.Type.Addr); >>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>> CG.If_true (handler, CG.Never); >>> cvs diff: Diffing stmts >>> Index: stmts/TryFinStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>> retrieving revision 1.6 >>> diff -u -w -r1.6 TryFinStmt.m3 >>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -299,6 +299,10 @@ >>> CG.Load_nil (); >>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> l := CG.Next_label (3); >>> CG.Set_label (l, barrier := TRUE); >>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>> Index: stmts/TryStmt.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>> retrieving revision 1.3 >>> diff -u -w -r1.3 TryStmt.m3 >>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>> @@ -10,7 +10,7 @@ >>> >>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>> >>> TYPE >>> @@ -411,6 +411,10 @@ >>> CG.Store_addr (frame, M3RT.EF1_exception); >>> ***********************************************) >>> >>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>> + CG.Load_nil (); >>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>> + >>> IF (p.hasElse) THEN >>> Marker.PushTryElse (l, l+1, frame); >>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>> >>> >>> The set_label before one of the PushEFrames could be moved down a bit, >>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>> >>> Thanks, >>> - Jay >>> >>> >>> ---------------------------------------- >>>> Subject: Re: [M3commit] CVS Update: cm3 >>>> From: hosking at cs.purdue.edu >>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>> CC: m3commit at elegosoft.com >>>> To: jay.krell at cornell.edu >>>> >>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>> >>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>> >>>> >>>> >>>> >>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>> >>>>> >>>>> I believe you can, but it'd take significant work in the frontend. >>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>> >>>>> >>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>> where in the function it is. >>>>> >>>>> >>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>> >>>>> >>>>> It is more work through, granted, I can understand that. >>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>> >>>>> >>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>> >>>>> >>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>> It aligns more. So it is using more stack than the other way. >>>>> And it might pessimize codegen in other ways. >>>>> >>>>> >>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>> >>>>> >>>>> - Jay >>>>> >>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>> since they can be nested. >>>>>> >>>>>> >>>>>> >>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>> >>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>> local "EF1" for each try. >>>>>> I guess, really, it is EF1, EF2, etc. >>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>> it in each EF* block? >>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>> to in the front end, I need to read it more. >>>>>> >>>>>> something like: >>>>>> >>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>> END END END END F1; >>>>>> => >>>>>> >>>>>> void F1() >>>>>> { >>>>>> jmp_buf* jb = 0; >>>>>> EF1 a,b,c; >>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>> do stuff 1... >>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>> do stuff 2... >>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>> do stuff 3... >>>>>> } >>>>>> >>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>> or the other, and that assignment is expression..I quite like those >>>>>> features....) >>>>>> >>>>>> >>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>> >>>>>> >>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>> additional progress, you only ever know the last place you were in a >>>>>> function. >>>>>> That doesn't seem adequate. >>>>>> >>>>>> >>>>>> What if a function raises an exception, catches it within itself, and >>>>>> then raises something else, and then wants to catch that? >>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>> same place. >>>>>> >>>>>> >>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>> across functions. >>>>>> I think somehow that is related here. >>>>>> >>>>>> >>>>>> e.g. how would you ensure forward progress in this: >>>>>> >>>>>> >>>>>> EXCEPTION E1; >>>>>> EXCEPTION E2; >>>>>> EXCEPTION E3; >>>>>> >>>>>> >>>>>> PROCEDURE F4() RAISES ANY = >>>>>> CONST Function = "F4 "; >>>>>> BEGIN >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> TRY >>>>>> Put(Function & Int(Line())); NL(); >>>>>> RAISE E1; >>>>>> EXCEPT ELSE >>>>>> RAISE E2; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> RAISE E3; >>>>>> END; >>>>>> EXCEPT ELSE >>>>>> END; >>>>>> END F4; >>>>>> >>>>>> >>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> I am OK with what you have currently: >>>>>> >>>>>> At each TRY: >>>>>> >>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>> if the corresponding local variable is NIL. >>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>> 3. Execute the try block. >>>>>> >>>>>> As you say, alloca should turn into an inline operation using the >>>>>> compiler's builtin implementation of alloca. >>>>>> >>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>> >>>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>> is as poor as it is, since a better but still >>>>>> portable implementation doesn't seem too too difficult. >>>>>> >>>>>> >>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>> setjmp/alloca/pushframe per function? >>>>>> Using a local integer to record the position within the function? >>>>>> >>>>>> >>>>>> Or just give me a week or few to get stack walking working and then >>>>>> live the regression on other targets? >>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>> possible; NT does have a decent runtime here..) >>>>>> >>>>>> >>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>> >>>>>> >>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>> >>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>> merges, than n calls to alloca? >>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>> setjmp and n calls to pthread_getspecific. >>>>>> The alloca calls will be dwarfed. >>>>>> Code size will suffer. >>>>>> >>>>>> >>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>> setjmp/pthread_getspecific is used. >>>>>> >>>>>> >>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>> per function >>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>> of how many calls it makes per function, >>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>> >>>>>> >>>>>> So, yes, given my current understanding, it is progress. >>>>>> The target-dependence is not worth it, imho. >>>>>> I'll still do some comparisons to release. >>>>>> >>>>>> >>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>> >>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>> I'll do more testing. >>>>>> >>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>> >>>>>> >>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>> the preexisting inefficiency. >>>>>> And the preexisting inefficiency is way more than the increase. >>>>>> >>>>>> And second, either way, it could be better. >>>>>> >>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>> it calls setjmp once. >>>>>> And then, it should have one volatile integer, that in a sense >>>>>> represents the line number. >>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>> incremented, every time you >>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>> value can be stored. >>>>>> And then there is a maximum of one one handler per function, it >>>>>> switches on the integer >>>>>> to decide where it got into the function and what it should do. >>>>>> >>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>> >>>>>> - Jay >>>>>> >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>> >>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>> it -- check for NIL. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>> CC: m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>> are allocating on every TRY where previously the storage was statically >>>>>> allocated. Do you really think this is progress? >>>>>> >>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>> >>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>> actually fairly small to read. >>>>>> I understand it is definitely less efficient, a few more instructions >>>>>> for every try/lock. >>>>>> No extra function call, at least with gcc backend. >>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>> is written so that it should work >>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>> probably is a function call there. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>> From: jay.krell at cornell.edu >>>>>> To: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>> CC: m3commit at elegosoft.com >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> >>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>> definitely a bit less efficient, but the significant advantage is >>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>> >>>>>> >>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>> the problem is addressed there. >>>>>> >>>>>> >>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>> walker. I wanted to do this first though, while more targets using >>>>>> setjmp. >>>>>> >>>>>> - Jay/phone >>>>>> >>>>>> ________________________________ >>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>> From: hosking at cs.purdue.edu >>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>> To: jay.krell at cornell.edu >>>>>> >>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>> has been done here without diving into the diff. >>>>>> >>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>> >>>>>> diff attached >>>>>> >>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>> To: m3commit at elegosoft.com >>>>>>> From: jkrell at elego.de >>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> CVSROOT: /usr/cvs >>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>> >>>>>>> Modified files: >>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>> >>>>>>> Log message: >>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>> >>>>>>> to allocate jmp_buf >>>>>>> >>>>>>> - eliminates a large swath of target-dependent code >>>>>>> - allows for covering up the inability to declare >>>>>>> types with alignment > 64 bits >>>>>>> >>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> > From hosking at cs.purdue.edu Thu Jan 6 22:00:08 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:00:08 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, Message-ID: In the code below there are no initializations. On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > ps: I think there other non-ideal initializations here. > e.g. > > > TryFinStmt.m3:Compile2 > (* declare and initialize the info record *) > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_procedure (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_handler); > CG.Load_static_link (p.handler.cg_proc); > CG.Store_addr (frame, M3RT.EF2_frame); > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > Granted, this is non-stack-walker code. > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > - Jay > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> CC: m3commit at elegosoft.com >> Subject: RE: [M3commit] CVS Update: cm3 >> Date: Thu, 6 Jan 2011 20:48:56 +0000 >> >> >> The same way as before. I think this operates at too low a level to get any automatic initialization. >> >> TryStmt.m3 and TryFinStmt.m3: >> >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >> CG.Type.Struct, 0, in_memory := TRUE, >> up_level := FALSE, f := CG.Never); >> >> I agree though, this might not be ideal. >> >> - Jay >> >> >> ---------------------------------------- >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> I don't understand what you mean by "initializes to NIL". >>> How are you creating the frame variable? >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>> >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>> >>>> >>>> Ok. >>>> Do you know where to initialize the jmpbuf to NIL? >>>> >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>> also initializes to NIL repeatedly, so no change effectively. >>>> >>>> >>>> Index: misc/Marker.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>> retrieving revision 1.7 >>>> diff -u -w -r1.7 Marker.m3 >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -233,6 +233,7 @@ >>>> >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>> VAR new: BOOLEAN; >>>> + label := CG.Next_label (); >>>> BEGIN >>>> (* int setjmp(void* ); *) >>>> IF (setjmp = NIL) THEN >>>> @@ -263,18 +264,25 @@ >>>> Target.Word.cg_type, 0); >>>> END; >>>> >>>> + (* IF frame.jmpbuf = NIL THEN *) >>>> + >>>> + CG.Load_nil (); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>> + >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>> CG.Pop_param (Target.Word.cg_type); >>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> + (* END *) >>>> + CG.Set_label (label); >>>> >>>> (* setmp(frame.jmpbuf) *) >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>> - Target.Address.cg_type); >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>> CG.Pop_param (CG.Type.Addr); >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>> CG.If_true (handler, CG.Never); >>>> cvs diff: Diffing stmts >>>> Index: stmts/TryFinStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>> retrieving revision 1.6 >>>> diff -u -w -r1.6 TryFinStmt.m3 >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -299,6 +299,10 @@ >>>> CG.Load_nil (); >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> l := CG.Next_label (3); >>>> CG.Set_label (l, barrier := TRUE); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>> Index: stmts/TryStmt.m3 >>>> =================================================================== >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>> retrieving revision 1.3 >>>> diff -u -w -r1.3 TryStmt.m3 >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>> @@ -10,7 +10,7 @@ >>>> >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>> >>>> TYPE >>>> @@ -411,6 +411,10 @@ >>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>> ***********************************************) >>>> >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>> + CG.Load_nil (); >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>> + >>>> IF (p.hasElse) THEN >>>> Marker.PushTryElse (l, l+1, frame); >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>> >>>> >>>> The set_label before one of the PushEFrames could be moved down a bit, >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>> >>>> Thanks, >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>> >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>> >>>>> >>>>> >>>>> >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>> >>>>>> >>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>> >>>>>> >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>> where in the function it is. >>>>>> >>>>>> >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>> >>>>>> >>>>>> It is more work through, granted, I can understand that. >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>> >>>>>> >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>> >>>>>> >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>> It aligns more. So it is using more stack than the other way. >>>>>> And it might pessimize codegen in other ways. >>>>>> >>>>>> >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>> >>>>>> >>>>>> - Jay >>>>>> >>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>> since they can be nested. >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>> >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>> local "EF1" for each try. >>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>> it in each EF* block? >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>> to in the front end, I need to read it more. >>>>>>> >>>>>>> something like: >>>>>>> >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>> END END END END F1; >>>>>>> => >>>>>>> >>>>>>> void F1() >>>>>>> { >>>>>>> jmp_buf* jb = 0; >>>>>>> EF1 a,b,c; >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>> do stuff 1... >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>> do stuff 2... >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>> do stuff 3... >>>>>>> } >>>>>>> >>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>> features....) >>>>>>> >>>>>>> >>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>> >>>>>>> >>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>> additional progress, you only ever know the last place you were in a >>>>>>> function. >>>>>>> That doesn't seem adequate. >>>>>>> >>>>>>> >>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>> then raises something else, and then wants to catch that? >>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>> same place. >>>>>>> >>>>>>> >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>> across functions. >>>>>>> I think somehow that is related here. >>>>>>> >>>>>>> >>>>>>> e.g. how would you ensure forward progress in this: >>>>>>> >>>>>>> >>>>>>> EXCEPTION E1; >>>>>>> EXCEPTION E2; >>>>>>> EXCEPTION E3; >>>>>>> >>>>>>> >>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>> CONST Function = "F4 "; >>>>>>> BEGIN >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> TRY >>>>>>> Put(Function & Int(Line())); NL(); >>>>>>> RAISE E1; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E2; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> RAISE E3; >>>>>>> END; >>>>>>> EXCEPT ELSE >>>>>>> END; >>>>>>> END F4; >>>>>>> >>>>>>> >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> I am OK with what you have currently: >>>>>>> >>>>>>> At each TRY: >>>>>>> >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>> if the corresponding local variable is NIL. >>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>> 3. Execute the try block. >>>>>>> >>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>> compiler's builtin implementation of alloca. >>>>>>> >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>> >>>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>> is as poor as it is, since a better but still >>>>>>> portable implementation doesn't seem too too difficult. >>>>>>> >>>>>>> >>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>> setjmp/alloca/pushframe per function? >>>>>>> Using a local integer to record the position within the function? >>>>>>> >>>>>>> >>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>> live the regression on other targets? >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>> possible; NT does have a decent runtime here..) >>>>>>> >>>>>>> >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>> >>>>>>> >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>> >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>> merges, than n calls to alloca? >>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>> The alloca calls will be dwarfed. >>>>>>> Code size will suffer. >>>>>>> >>>>>>> >>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>> setjmp/pthread_getspecific is used. >>>>>>> >>>>>>> >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>> per function >>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>> of how many calls it makes per function, >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>> >>>>>>> >>>>>>> So, yes, given my current understanding, it is progress. >>>>>>> The target-dependence is not worth it, imho. >>>>>>> I'll still do some comparisons to release. >>>>>>> >>>>>>> >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>> >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>> >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>> I'll do more testing. >>>>>>> >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>> >>>>>>> >>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>> the preexisting inefficiency. >>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>> >>>>>>> And second, either way, it could be better. >>>>>>> >>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>> it calls setjmp once. >>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>> represents the line number. >>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>> incremented, every time you >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>> value can be stored. >>>>>>> And then there is a maximum of one one handler per function, it >>>>>>> switches on the integer >>>>>>> to decide where it got into the function and what it should do. >>>>>>> >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>> >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>> it -- check for NIL. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>> allocated. Do you really think this is progress? >>>>>>> >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>> >>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>> actually fairly small to read. >>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>> for every try/lock. >>>>>>> No extra function call, at least with gcc backend. >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>> is written so that it should work >>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>> probably is a function call there. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> ________________________________ >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>> >>>>>>> >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>> the problem is addressed there. >>>>>>> >>>>>>> >>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>> setjmp. >>>>>>> >>>>>>> - Jay/phone >>>>>>> >>>>>>> ________________________________ >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>> has been done here without diving into the diff. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>> >>>>>>> diff attached >>>>>>> >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>> To: m3commit at elegosoft.com >>>>>>>> From: jkrell at elego.de >>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>> >>>>>>>> CVSROOT: /usr/cvs >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>> >>>>>>>> Modified files: >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>> >>>>>>>> Log message: >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>> >>>>>>>> to allocate jmp_buf >>>>>>>> >>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>> - allows for covering up the inability to declare >>>>>>>> types with alignment > 64 bits >>>>>>>> >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Thu Jan 6 22:17:03 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 6 Jan 2011 21:17:03 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:00:08 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > In the code below there are no initializations. > > On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > > > > ps: I think there other non-ideal initializations here. > > e.g. > > > > > > TryFinStmt.m3:Compile2 > > (* declare and initialize the info record *) > > frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_procedure (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_handler); > > CG.Load_static_link (p.handler.cg_proc); > > CG.Store_addr (frame, M3RT.EF2_frame); > > > > > > Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > Granted, this is non-stack-walker code. > > > > Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > > > - Jay > > > > ---------------------------------------- > >> From: jay.krell at cornell.edu > >> To: hosking at cs.purdue.edu > >> CC: m3commit at elegosoft.com > >> Subject: RE: [M3commit] CVS Update: cm3 > >> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >> > >> > >> The same way as before. I think this operates at too low a level to get any automatic initialization. > >> > >> TryStmt.m3 and TryFinStmt.m3: > >> > >> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >> CG.Type.Struct, 0, in_memory := TRUE, > >> up_level := FALSE, f := CG.Never); > >> > >> I agree though, this might not be ideal. > >> > >> - Jay > >> > >> > >> ---------------------------------------- > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> I don't understand what you mean by "initializes to NIL". > >>> How are you creating the frame variable? > >>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>> > >>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>> > >>>> > >>>> Ok. > >>>> Do you know where to initialize the jmpbuf to NIL? > >>>> > >>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>> also initializes to NIL repeatedly, so no change effectively. > >>>> > >>>> > >>>> Index: misc/Marker.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>> retrieving revision 1.7 > >>>> diff -u -w -r1.7 Marker.m3 > >>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -233,6 +233,7 @@ > >>>> > >>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>> VAR new: BOOLEAN; > >>>> + label := CG.Next_label (); > >>>> BEGIN > >>>> (* int setjmp(void* ); *) > >>>> IF (setjmp = NIL) THEN > >>>> @@ -263,18 +264,25 @@ > >>>> Target.Word.cg_type, 0); > >>>> END; > >>>> > >>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>> + > >>>> + CG.Load_nil (); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>> + > >>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>> CG.Pop_param (Target.Word.cg_type); > >>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> + (* END *) > >>>> + CG.Set_label (label); > >>>> > >>>> (* setmp(frame.jmpbuf) *) > >>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>> - Target.Address.cg_type); > >>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>> CG.Pop_param (CG.Type.Addr); > >>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>> CG.If_true (handler, CG.Never); > >>>> cvs diff: Diffing stmts > >>>> Index: stmts/TryFinStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>> retrieving revision 1.6 > >>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -299,6 +299,10 @@ > >>>> CG.Load_nil (); > >>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> l := CG.Next_label (3); > >>>> CG.Set_label (l, barrier := TRUE); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>> Index: stmts/TryStmt.m3 > >>>> =================================================================== > >>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>> retrieving revision 1.3 > >>>> diff -u -w -r1.3 TryStmt.m3 > >>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>> @@ -10,7 +10,7 @@ > >>>> > >>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>> > >>>> TYPE > >>>> @@ -411,6 +411,10 @@ > >>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>> ***********************************************) > >>>> > >>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>> + CG.Load_nil (); > >>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>> + > >>>> IF (p.hasElse) THEN > >>>> Marker.PushTryElse (l, l+1, frame); > >>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>> > >>>> > >>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>> > >>>> Thanks, > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>> > >>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>> > >>>>>> > >>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>> where in the function it is. > >>>>>> > >>>>>> > >>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>> > >>>>>> > >>>>>> It is more work through, granted, I can understand that. > >>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>> > >>>>>> > >>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>> > >>>>>> > >>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>> It aligns more. So it is using more stack than the other way. > >>>>>> And it might pessimize codegen in other ways. > >>>>>> > >>>>>> > >>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>> > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>> since they can be nested. > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>> > >>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>> local "EF1" for each try. > >>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>> it in each EF* block? > >>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>> to in the front end, I need to read it more. > >>>>>>> > >>>>>>> something like: > >>>>>>> > >>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>> END END END END F1; > >>>>>>> => > >>>>>>> > >>>>>>> void F1() > >>>>>>> { > >>>>>>> jmp_buf* jb = 0; > >>>>>>> EF1 a,b,c; > >>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>> do stuff 1... > >>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>> do stuff 2... > >>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>> do stuff 3... > >>>>>>> } > >>>>>>> > >>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>> features....) > >>>>>>> > >>>>>>> > >>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>> > >>>>>>> > >>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>> function. > >>>>>>> That doesn't seem adequate. > >>>>>>> > >>>>>>> > >>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>> then raises something else, and then wants to catch that? > >>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>> same place. > >>>>>>> > >>>>>>> > >>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>> across functions. > >>>>>>> I think somehow that is related here. > >>>>>>> > >>>>>>> > >>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>> > >>>>>>> > >>>>>>> EXCEPTION E1; > >>>>>>> EXCEPTION E2; > >>>>>>> EXCEPTION E3; > >>>>>>> > >>>>>>> > >>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>> CONST Function = "F4 "; > >>>>>>> BEGIN > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> TRY > >>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>> RAISE E1; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E2; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> RAISE E3; > >>>>>>> END; > >>>>>>> EXCEPT ELSE > >>>>>>> END; > >>>>>>> END F4; > >>>>>>> > >>>>>>> > >>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> I am OK with what you have currently: > >>>>>>> > >>>>>>> At each TRY: > >>>>>>> > >>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>> if the corresponding local variable is NIL. > >>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>> 3. Execute the try block. > >>>>>>> > >>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>> compiler's builtin implementation of alloca. > >>>>>>> > >>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>> > >>>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>> is as poor as it is, since a better but still > >>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>> > >>>>>>> > >>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>> setjmp/alloca/pushframe per function? > >>>>>>> Using a local integer to record the position within the function? > >>>>>>> > >>>>>>> > >>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>> live the regression on other targets? > >>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>> possible; NT does have a decent runtime here..) > >>>>>>> > >>>>>>> > >>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>> > >>>>>>> > >>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>> > >>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>> merges, than n calls to alloca? > >>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>> The alloca calls will be dwarfed. > >>>>>>> Code size will suffer. > >>>>>>> > >>>>>>> > >>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>> setjmp/pthread_getspecific is used. > >>>>>>> > >>>>>>> > >>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>> per function > >>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>> of how many calls it makes per function, > >>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>> > >>>>>>> > >>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>> The target-dependence is not worth it, imho. > >>>>>>> I'll still do some comparisons to release. > >>>>>>> > >>>>>>> > >>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>> > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>> > >>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>> I'll do more testing. > >>>>>>> > >>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>> > >>>>>>> > >>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>> the preexisting inefficiency. > >>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>> > >>>>>>> And second, either way, it could be better. > >>>>>>> > >>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>> it calls setjmp once. > >>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>> represents the line number. > >>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>> incremented, every time you > >>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>> value can be stored. > >>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>> switches on the integer > >>>>>>> to decide where it got into the function and what it should do. > >>>>>>> > >>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>> > >>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>> it -- check for NIL. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>> allocated. Do you really think this is progress? > >>>>>>> > >>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>> > >>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>> actually fairly small to read. > >>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>> for every try/lock. > >>>>>>> No extra function call, at least with gcc backend. > >>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>> is written so that it should work > >>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>> probably is a function call there. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> > >>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>> > >>>>>>> > >>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>> the problem is addressed there. > >>>>>>> > >>>>>>> > >>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>> setjmp. > >>>>>>> > >>>>>>> - Jay/phone > >>>>>>> > >>>>>>> ________________________________ > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>> has been done here without diving into the diff. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>> > >>>>>>> diff attached > >>>>>>> > >>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>> To: m3commit at elegosoft.com > >>>>>>>> From: jkrell at elego.de > >>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>> > >>>>>>>> CVSROOT: /usr/cvs > >>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>> > >>>>>>>> Modified files: > >>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>> > >>>>>>>> Log message: > >>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>> > >>>>>>>> to allocate jmp_buf > >>>>>>>> > >>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>> - allows for covering up the inability to declare > >>>>>>>> types with alignment > 64 bits > >>>>>>>> > >>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > From hosking at cs.purdue.edu Thu Jan 6 22:56:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 16:56:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , Message-ID: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> You are confusing code emitted in the body of the loop with dynamic executions of that code. CG calls are all compile-time generation of code. On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > - Jay > > ---------------------------------------- >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 16:00:08 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> In the code below there are no initializations. >> >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >> >>> >>> ps: I think there other non-ideal initializations here. >>> e.g. >>> >>> >>> TryFinStmt.m3:Compile2 >>> (* declare and initialize the info record *) >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, >>> CG.Type.Struct, 0, in_memory := TRUE, >>> up_level := FALSE, f := CG.Never); >>> CG.Load_procedure (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_handler); >>> CG.Load_static_link (p.handler.cg_proc); >>> CG.Store_addr (frame, M3RT.EF2_frame); >>> >>> >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. >>> Granted, this is non-stack-walker code. >>> >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. >>> >>> - Jay >>> >>> ---------------------------------------- >>>> From: jay.krell at cornell.edu >>>> To: hosking at cs.purdue.edu >>>> CC: m3commit at elegosoft.com >>>> Subject: RE: [M3commit] CVS Update: cm3 >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>> >>>> >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. >>>> >>>> TryStmt.m3 and TryFinStmt.m3: >>>> >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, >>>> CG.Type.Struct, 0, in_memory := TRUE, >>>> up_level := FALSE, f := CG.Never); >>>> >>>> I agree though, this might not be ideal. >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> I don't understand what you mean by "initializes to NIL". >>>>> How are you creating the frame variable? >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. >>>>> >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>> >>>>>> >>>>>> Ok. >>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>> >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>> >>>>>> >>>>>> Index: misc/Marker.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>> retrieving revision 1.7 >>>>>> diff -u -w -r1.7 Marker.m3 >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -233,6 +233,7 @@ >>>>>> >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>> VAR new: BOOLEAN; >>>>>> + label := CG.Next_label (); >>>>>> BEGIN >>>>>> (* int setjmp(void* ); *) >>>>>> IF (setjmp = NIL) THEN >>>>>> @@ -263,18 +264,25 @@ >>>>>> Target.Word.cg_type, 0); >>>>>> END; >>>>>> >>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>> + >>>>>> + CG.Load_nil (); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); >>>>>> + >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> + (* END *) >>>>>> + CG.Set_label (label); >>>>>> >>>>>> (* setmp(frame.jmpbuf) *) >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, >>>>>> - Target.Address.cg_type); >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>> CG.Pop_param (CG.Type.Addr); >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>> CG.If_true (handler, CG.Never); >>>>>> cvs diff: Diffing stmts >>>>>> Index: stmts/TryFinStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>> retrieving revision 1.6 >>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -299,6 +299,10 @@ >>>>>> CG.Load_nil (); >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> l := CG.Next_label (3); >>>>>> CG.Set_label (l, barrier := TRUE); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>> Index: stmts/TryStmt.m3 >>>>>> =================================================================== >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>> retrieving revision 1.3 >>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>> @@ -10,7 +10,7 @@ >>>>>> >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>> >>>>>> TYPE >>>>>> @@ -411,6 +411,10 @@ >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>> ***********************************************) >>>>>> >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>> + CG.Load_nil (); >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>> + >>>>>> IF (p.hasElse) THEN >>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>> >>>>>> >>>>>> The set_label before one of the PushEFrames could be moved down a bit, >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. >>>>>> >>>>>> Thanks, >>>>>> - Jay >>>>>> >>>>>> >>>>>> ---------------------------------------- >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>> From: hosking at cs.purdue.edu >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>> CC: m3commit at elegosoft.com >>>>>>> To: jay.krell at cornell.edu >>>>>>> >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. >>>>>>> >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>> >>>>>>>> >>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>> >>>>>>>> >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate >>>>>>>> where in the function it is. >>>>>>>> >>>>>>>> >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>> >>>>>>>> >>>>>>>> It is more work through, granted, I can understand that. >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. >>>>>>>> >>>>>>>> >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>> >>>>>>>> >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. >>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>> And it might pessimize codegen in other ways. >>>>>>>> >>>>>>>> >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. >>>>>>>> >>>>>>>> >>>>>>>> - Jay >>>>>>>> >>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, >>>>>>>>> since they can be nested. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a >>>>>>>>> local "EF1" for each try. >>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store >>>>>>>>> it in each EF* block? >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how >>>>>>>>> to in the front end, I need to read it more. >>>>>>>>> >>>>>>>>> something like: >>>>>>>>> >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 >>>>>>>>> END END END END F1; >>>>>>>>> => >>>>>>>>> >>>>>>>>> void F1() >>>>>>>>> { >>>>>>>>> jmp_buf* jb = 0; >>>>>>>>> EF1 a,b,c; >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 >>>>>>>>> do stuff 1... >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 >>>>>>>>> do stuff 2... >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 >>>>>>>>> do stuff 3... >>>>>>>>> } >>>>>>>>> >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the >>>>>>>>> existance of the ternary operator, and that it only evaluates one side >>>>>>>>> or the other, and that assignment is expression..I quite like those >>>>>>>>> features....) >>>>>>>>> >>>>>>>>> >>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>> >>>>>>>>> >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>> additional progress, you only ever know the last place you were in a >>>>>>>>> function. >>>>>>>>> That doesn't seem adequate. >>>>>>>>> >>>>>>>>> >>>>>>>>> What if a function raises an exception, catches it within itself, and >>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the >>>>>>>>> same place. >>>>>>>>> >>>>>>>>> >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is >>>>>>>>> across functions. >>>>>>>>> I think somehow that is related here. >>>>>>>>> >>>>>>>>> >>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>> >>>>>>>>> >>>>>>>>> EXCEPTION E1; >>>>>>>>> EXCEPTION E2; >>>>>>>>> EXCEPTION E3; >>>>>>>>> >>>>>>>>> >>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>> CONST Function = "F4 "; >>>>>>>>> BEGIN >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> TRY >>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>> RAISE E1; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E2; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> RAISE E3; >>>>>>>>> END; >>>>>>>>> EXCEPT ELSE >>>>>>>>> END; >>>>>>>>> END F4; >>>>>>>>> >>>>>>>>> >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> I am OK with what you have currently: >>>>>>>>> >>>>>>>>> At each TRY: >>>>>>>>> >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking >>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>> 3. Execute the try block. >>>>>>>>> >>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>> >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>> >>>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation >>>>>>>>> is as poor as it is, since a better but still >>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>> >>>>>>>>> >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>> >>>>>>>>> >>>>>>>>> Or just give me a week or few to get stack walking working and then >>>>>>>>> live the regression on other targets? >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly >>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>> >>>>>>>>> >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. >>>>>>>>> >>>>>>>>> >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>> >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your >>>>>>>>> point is, you'd rather have n locals, which the backend automatically >>>>>>>>> merges, than n calls to alloca? >>>>>>>>> It's not a huge difference -- there are still going to be n calls to >>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>> Code size will suffer. >>>>>>>>> >>>>>>>>> >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if >>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>> >>>>>>>>> >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific >>>>>>>>> per function >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track >>>>>>>>> of how many calls it makes per function, >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>> >>>>>>>>> >>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>> I'll still do some comparisons to release. >>>>>>>>> >>>>>>>>> >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. >>>>>>>>> >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>> I'll do more testing. >>>>>>>>> >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>> >>>>>>>>> >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of >>>>>>>>> the preexisting inefficiency. >>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>> >>>>>>>>> And second, either way, it could be better. >>>>>>>>> >>>>>>>>> Basically, the model should be, that if a function has any try or lock, >>>>>>>>> it calls setjmp once. >>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>> represents the line number. >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is >>>>>>>>> incremented, every time you >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the >>>>>>>>> value can be stored. >>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>> switches on the integer >>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>> >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix >>>>>>>>> it -- check for NIL. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you >>>>>>>>> are allocating on every TRY where previously the storage was statically >>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>> >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is >>>>>>>>> actually fairly small to read. >>>>>>>>> I understand it is definitely less efficient, a few more instructions >>>>>>>>> for every try/lock. >>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change >>>>>>>>> is written so that it should work >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there >>>>>>>>> probably is a function call there. >>>>>>>>> >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. >>>>>>>>> >>>>>>>>> >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if >>>>>>>>> the problem is addressed there. >>>>>>>>> >>>>>>>>> >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack >>>>>>>>> walker. I wanted to do this first though, while more targets using >>>>>>>>> setjmp. >>>>>>>>> >>>>>>>>> - Jay/phone >>>>>>>>> >>>>>>>>> ________________________________ >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>> >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what >>>>>>>>> has been done here without diving into the diff. >>>>>>>>> >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>> >>>>>>>>> diff attached >>>>>>>>> >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>> From: jkrell at elego.de >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>> >>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>> >>>>>>>>>> Modified files: >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>> >>>>>>>>>> Log message: >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>> >>>>>>>>>> to allocate jmp_buf >>>>>>>>>> >>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>> types with alignment > 64 bits >>>>>>>>>> >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 05:08:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 04:08:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: I don't think so, but maybe. For i := 1 to 10 do try finally end will run that generated code 10 times but only the 1st is needed. In general? I not sure. Jay/phone > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 16:56:48 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > CG calls are all compile-time generation of code. > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > - Jay > > > > ---------------------------------------- > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> In the code below there are no initializations. > >> > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >> > >>> > >>> ps: I think there other non-ideal initializations here. > >>> e.g. > >>> > >>> > >>> TryFinStmt.m3:Compile2 > >>> (* declare and initialize the info record *) > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > >>> CG.Type.Struct, 0, in_memory := TRUE, > >>> up_level := FALSE, f := CG.Never); > >>> CG.Load_procedure (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_handler); > >>> CG.Load_static_link (p.handler.cg_proc); > >>> CG.Store_addr (frame, M3RT.EF2_frame); > >>> > >>> > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > >>> Granted, this is non-stack-walker code. > >>> > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > >>> > >>> - Jay > >>> > >>> ---------------------------------------- > >>>> From: jay.krell at cornell.edu > >>>> To: hosking at cs.purdue.edu > >>>> CC: m3commit at elegosoft.com > >>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>> > >>>> > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > >>>> > >>>> TryStmt.m3 and TryFinStmt.m3: > >>>> > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > >>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>> up_level := FALSE, f := CG.Never); > >>>> > >>>> I agree though, this might not be ideal. > >>>> > >>>> - Jay > >>>> > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> I don't understand what you mean by "initializes to NIL". > >>>>> How are you creating the frame variable? > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > >>>>> > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> Ok. > >>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>> > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>> > >>>>>> > >>>>>> Index: misc/Marker.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>> retrieving revision 1.7 > >>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -233,6 +233,7 @@ > >>>>>> > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>> VAR new: BOOLEAN; > >>>>>> + label := CG.Next_label (); > >>>>>> BEGIN > >>>>>> (* int setjmp(void* ); *) > >>>>>> IF (setjmp = NIL) THEN > >>>>>> @@ -263,18 +264,25 @@ > >>>>>> Target.Word.cg_type, 0); > >>>>>> END; > >>>>>> > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>> + > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > >>>>>> + > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> + (* END *) > >>>>>> + CG.Set_label (label); > >>>>>> > >>>>>> (* setmp(frame.jmpbuf) *) > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > >>>>>> - Target.Address.cg_type); > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>> CG.If_true (handler, CG.Never); > >>>>>> cvs diff: Diffing stmts > >>>>>> Index: stmts/TryFinStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>> retrieving revision 1.6 > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -299,6 +299,10 @@ > >>>>>> CG.Load_nil (); > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> l := CG.Next_label (3); > >>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>> Index: stmts/TryStmt.m3 > >>>>>> =================================================================== > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>> retrieving revision 1.3 > >>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>> @@ -10,7 +10,7 @@ > >>>>>> > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>> > >>>>>> TYPE > >>>>>> @@ -411,6 +411,10 @@ > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>> ***********************************************) > >>>>>> > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>> + CG.Load_nil (); > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>> + > >>>>>> IF (p.hasElse) THEN > >>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>> > >>>>>> > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > >>>>>> > >>>>>> Thanks, > >>>>>> - Jay > >>>>>> > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>> From: hosking at cs.purdue.edu > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> To: jay.krell at cornell.edu > >>>>>>> > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > >>>>>>> > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>> > >>>>>>>> > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>> > >>>>>>>> > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > >>>>>>>> where in the function it is. > >>>>>>>> > >>>>>>>> > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>> > >>>>>>>> > >>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > >>>>>>>> > >>>>>>>> > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>> > >>>>>>>> > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > >>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>> > >>>>>>>> > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > >>>>>>>> > >>>>>>>> > >>>>>>>> - Jay > >>>>>>>> > >>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > >>>>>>>>> since they can be nested. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > >>>>>>>>> local "EF1" for each try. > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > >>>>>>>>> it in each EF* block? > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > >>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>> > >>>>>>>>> something like: > >>>>>>>>> > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > >>>>>>>>> END END END END F1; > >>>>>>>>> => > >>>>>>>>> > >>>>>>>>> void F1() > >>>>>>>>> { > >>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>> EF1 a,b,c; > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > >>>>>>>>> do stuff 1... > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > >>>>>>>>> do stuff 2... > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > >>>>>>>>> do stuff 3... > >>>>>>>>> } > >>>>>>>>> > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > >>>>>>>>> or the other, and that assignment is expression..I quite like those > >>>>>>>>> features....) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>> additional progress, you only ever know the last place you were in a > >>>>>>>>> function. > >>>>>>>>> That doesn't seem adequate. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> What if a function raises an exception, catches it within itself, and > >>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > >>>>>>>>> same place. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > >>>>>>>>> across functions. > >>>>>>>>> I think somehow that is related here. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> EXCEPTION E1; > >>>>>>>>> EXCEPTION E2; > >>>>>>>>> EXCEPTION E3; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>> CONST Function = "F4 "; > >>>>>>>>> BEGIN > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> TRY > >>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>> RAISE E1; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E2; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> RAISE E3; > >>>>>>>>> END; > >>>>>>>>> EXCEPT ELSE > >>>>>>>>> END; > >>>>>>>>> END F4; > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> I am OK with what you have currently: > >>>>>>>>> > >>>>>>>>> At each TRY: > >>>>>>>>> > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > >>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>> 3. Execute the try block. > >>>>>>>>> > >>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>> > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > >>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Or just give me a week or few to get stack walking working and then > >>>>>>>>> live the regression on other targets? > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > >>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>> > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > >>>>>>>>> merges, than n calls to alloca? > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > >>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>> Code size will suffer. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > >>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > >>>>>>>>> per function > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > >>>>>>>>> of how many calls it makes per function, > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>> I'll do more testing. > >>>>>>>>> > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > >>>>>>>>> the preexisting inefficiency. > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>> > >>>>>>>>> And second, either way, it could be better. > >>>>>>>>> > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > >>>>>>>>> it calls setjmp once. > >>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>> represents the line number. > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > >>>>>>>>> incremented, every time you > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > >>>>>>>>> value can be stored. > >>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>> switches on the integer > >>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>> > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > >>>>>>>>> it -- check for NIL. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > >>>>>>>>> are allocating on every TRY where previously the storage was statically > >>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > >>>>>>>>> actually fairly small to read. > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > >>>>>>>>> for every try/lock. > >>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > >>>>>>>>> is written so that it should work > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > >>>>>>>>> probably is a function call there. > >>>>>>>>> > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > >>>>>>>>> the problem is addressed there. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > >>>>>>>>> walker. I wanted to do this first though, while more targets using > >>>>>>>>> setjmp. > >>>>>>>>> > >>>>>>>>> - Jay/phone > >>>>>>>>> > >>>>>>>>> ________________________________ > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>> > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > >>>>>>>>> has been done here without diving into the diff. > >>>>>>>>> > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>> > >>>>>>>>> diff attached > >>>>>>>>> > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>> > >>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>> > >>>>>>>>>> Modified files: > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>> > >>>>>>>>>> Log message: > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>> > >>>>>>>>>> to allocate jmp_buf > >>>>>>>>>> > >>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>> > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>>> > >>> > >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 7 05:24:31 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 6 Jan 2011 23:24:31 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> Message-ID: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Ah, yes, I see. You're right. The same proc is stored multiple times. We could indeed simply have a variable initialized once with the value of the proc. On Jan 6, 2011, at 11:08 PM, Jay K wrote: > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp implementation to one that relies on unwind support, so I don't think the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to return to. > > >>>>>>>> There would also be a volatile local integer, that gets altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code -- the > > >>>>>>>>> existance of the ternary operator, and that it only evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. But now you > > >>>>>>>>> are allocating on every TRY where previously the storage was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 7 06:38:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 05:38:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Now, for all I know it is loading from a variable and the variable can change. That's my uncertainty. There is other similar code that I'm even less certain of, specifically: MODULE TryStmt; PROCEDURE Compile1 (p: P): Stmt.Outcomes = ??? (* declare and initialize the info record *) ??? info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, ????????????????????????????? CG.Type.Struct, 0, in_memory := TRUE, ????????????????????????????? up_level := FALSE, f := CG.Never); ??? CG.Load_nil (); ??? CG.Store_addr (info, M3RT.EA_exception); It could very well be that in: ?For i := 1 to 10 do try ... may or may not throw ... except else info needs to be nulled each time through. If you fixup this stuff, I'll know more easily how to remove the allocas from loops. Or maybe I can figure it out anyway from your clue. (Or maybe I'll first go after Mika's two failing pieces of code..) Thanks, ?- Jay ________________________________ > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Thu, 6 Jan 2011 23:24:31 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Ah, yes, I see. You're right. > The same proc is stored multiple times. > We could indeed simply have a variable initialized once with the value > of the proc. > > > On Jan 6, 2011, at 11:08 PM, Jay K wrote: > > I don't think so, but maybe. > > For i := 1 to 10 do try finally end > > will run that generated code 10 times but only the 1st is needed. In > general? I not sure. > > Jay/phone > > > Subject: Re: [M3commit] CVS Update: cm3 > > From: hosking at cs.purdue.edu > > Date: Thu, 6 Jan 2011 16:56:48 -0500 > > CC: m3commit at elegosoft.com > > To: jay.krell at cornell.edu > > > > You are confusing code emitted in the body of the loop with dynamic > executions of that code. > > CG calls are all compile-time generation of code. > > > > On Jan 6, 2011, at 4:17 PM, Jay K wrote: > > > > > > > > If I have a try/finally or lock in a loop, those lines aren't going > to guaranteeably store the same values each time? > > > > > > - Jay > > > > > > ---------------------------------------- > > >> Subject: Re: [M3commit] CVS Update: cm3 > > >> From: hosking at cs.purdue.edu > > >> Date: Thu, 6 Jan 2011 16:00:08 -0500 > > >> CC: m3commit at elegosoft.com > > >> To: jay.krell at cornell.edu > > >> > > >> In the code below there are no initializations. > > >> > > >> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > > >> > > >>> > > >>> ps: I think there other non-ideal initializations here. > > >>> e.g. > > >>> > > >>> > > >>> TryFinStmt.m3:Compile2 > > >>> (* declare and initialize the info record *) > > >>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > Target.Address.align, > > >>> CG.Type.Struct, 0, in_memory := TRUE, > > >>> up_level := FALSE, f := CG.Never); > > >>> CG.Load_procedure (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_handler); > > >>> CG.Load_static_link (p.handler.cg_proc); > > >>> CG.Store_addr (frame, M3RT.EF2_frame); > > >>> > > >>> > > >>> Putting TRY/LOCK in loops probably repeatedly does the same > initializations. > > >>> Granted, this is non-stack-walker code. > > >>> > > >>> Seems all bit a suspicious to me, though I'm pretty ignorant of > m3front still.. > > >>> > > >>> - Jay > > >>> > > >>> ---------------------------------------- > > >>>> From: jay.krell at cornell.edu > > >>>> To: hosking at cs.purdue.edu > > >>>> CC: m3commit at elegosoft.com > > >>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > > >>>> > > >>>> > > >>>> The same way as before. I think this operates at too low a level > to get any automatic initialization. > > >>>> > > >>>> TryStmt.m3 and TryFinStmt.m3: > > >>>> > > >>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > Target.Address.align, > > >>>> CG.Type.Struct, 0, in_memory := TRUE, > > >>>> up_level := FALSE, f := CG.Never); > > >>>> > > >>>> I agree though, this might not be ideal. > > >>>> > > >>>> - Jay > > >>>> > > >>>> > > >>>> ---------------------------------------- > > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>> From: hosking at cs.purdue.edu > > >>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > > >>>>> CC: m3commit at elegosoft.com > > >>>>> To: jay.krell at cornell.edu > > >>>>> > > >>>>> I don't understand what you mean by "initializes to NIL". > > >>>>> How are you creating the frame variable? > > >>>>> If you do it properly the language semantics will cause it be > initialized to NIL automatically. > > >>>>> > > >>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > > >>>>> > > >>>>>> > > >>>>>> Ok. > > >>>>>> Do you know where to initialize the jmpbuf to NIL? > > >>>>>> > > >>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > to correct, > > >>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > > >>>>>> also initializes to NIL repeatedly, so no change effectively. > > >>>>>> > > >>>>>> > > >>>>>> Index: misc/Marker.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > > >>>>>> retrieving revision 1.7 > > >>>>>> diff -u -w -r1.7 Marker.m3 > > >>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > > >>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -233,6 +233,7 @@ > > >>>>>> > > >>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > > >>>>>> VAR new: BOOLEAN; > > >>>>>> + label := CG.Next_label (); > > >>>>>> BEGIN > > >>>>>> (* int setjmp(void* ); *) > > >>>>>> IF (setjmp = NIL) THEN > > >>>>>> @@ -263,18 +264,25 @@ > > >>>>>> Target.Word.cg_type, 0); > > >>>>>> END; > > >>>>>> > > >>>>>> + (* IF frame.jmpbuf = NIL THEN *) > > >>>>>> + > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > CG.Maybe); > > >>>>>> + > > >>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > > >>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > > >>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > > >>>>>> CG.Pop_param (Target.Word.cg_type); > > >>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > > >>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> + (* END *) > > >>>>>> + CG.Set_label (label); > > >>>>>> > > >>>>>> (* setmp(frame.jmpbuf) *) > > >>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > > >>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > Target.Address.align, > > >>>>>> - Target.Address.cg_type); > > >>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> CG.Pop_param (CG.Type.Addr); > > >>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > > >>>>>> CG.If_true (handler, CG.Never); > > >>>>>> cvs diff: Diffing stmts > > >>>>>> Index: stmts/TryFinStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > > >>>>>> retrieving revision 1.6 > > >>>>>> diff -u -w -r1.6 TryFinStmt.m3 > > >>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > > >>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -299,6 +299,10 @@ > > >>>>>> CG.Load_nil (); > > >>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> l := CG.Next_label (3); > > >>>>>> CG.Set_label (l, barrier := TRUE); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > > >>>>>> Index: stmts/TryStmt.m3 > > >>>>>> =================================================================== > > >>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > > >>>>>> retrieving revision 1.3 > > >>>>>> diff -u -w -r1.3 TryStmt.m3 > > >>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > > >>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > > >>>>>> @@ -10,7 +10,7 @@ > > >>>>>> > > >>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > Error, Marker; > > >>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > > >>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > > >>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > > >>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > > >>>>>> > > >>>>>> TYPE > > >>>>>> @@ -411,6 +411,10 @@ > > >>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > > >>>>>> ***********************************************) > > >>>>>> > > >>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > > >>>>>> + CG.Load_nil (); > > >>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > > >>>>>> + > > >>>>>> IF (p.hasElse) THEN > > >>>>>> Marker.PushTryElse (l, l+1, frame); > > >>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > > >>>>>> > > >>>>>> > > >>>>>> The set_label before one of the PushEFrames could be moved > down a bit, > > >>>>>> to after the NIL initialization, and that'd fix some cases, > but I think not all. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> - Jay > > >>>>>> > > >>>>>> > > >>>>>> ---------------------------------------- > > >>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>> From: hosking at cs.purdue.edu > > >>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > > >>>>>>> CC: m3commit at elegosoft.com > > >>>>>>> To: jay.krell at cornell.edu > > >>>>>>> > > >>>>>>> At this point, we are trying to move away from the setjmp > implementation to one that relies on unwind support, so I don't think > the effort here is worthwhile. > > >>>>>>> > > >>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > > >>>>>>> > > >>>>>>>> > > >>>>>>>> I believe you can, but it'd take significant work in the frontend. > > >>>>>>>> The jmpbuf should identify merely which procedure/frame to > return to. > > >>>>>>>> There would also be a volatile local integer, that gets > altered at certain points through the function. > > >>>>>>>> When setjmp returns exceptionally, you'd switch on that > integer to determine where to "really" go. > > >>>>>>>> This is analogous to how other systems work -- NT/x86 has a > highly optimized frame based exception > > >>>>>>>> handling. Instead of a generic thread local, FS:0 is > reserved to be the head of the linked list of frames. > > >>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> So the result is that a function with one or more tries, or > one or more locals with destructors, > > >>>>>>>> puts one node on the FS:0 list, and then mucks with the > volatile local integer to indicate > > >>>>>>>> where in the function it is. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> If NT/x86 were inefficient more analogous to current > Modula-3, it'd link/unlink in FS:0 more often. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> It is more work through, granted, I can understand that. > > >>>>>>>> And given that we have a much better option for many > platforms, the payoff would be reduced. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> I should point out that alloca has an extra inefficiency vs. > the previous approach. > > >>>>>>>> It aligns more. So it is using more stack than the other way. > > >>>>>>>> And it might pessimize codegen in other ways. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> The gcc code appears somewhat similar..I think the tables > merely describe, again, which > > >>>>>>>> function/frame to return to, and that within the frame there > is a local integer to determine > > >>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > switch. > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> - Jay > > >>>>>>>> > > >>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> You can't have one jmpbuf per procedure. You need one per > TRY scope, > > >>>>>>>>> since they can be nested. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Hm. How do I single instance the "EF1"? The current code > allocates a > > >>>>>>>>> local "EF1" for each try. > > >>>>>>>>> I guess, really, it is EF1, EF2, etc. > > >>>>>>>>> So there should be a separate local for the jmpbuf pointer, > and store > > >>>>>>>>> it in each EF* block? > > >>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > figure out how > > >>>>>>>>> to in the front end, I need to read it more. > > >>>>>>>>> > > >>>>>>>>> something like: > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > do stuff 3 > > >>>>>>>>> END END END END F1; > > >>>>>>>>> => > > >>>>>>>>> > > >>>>>>>>> void F1() > > >>>>>>>>> { > > >>>>>>>>> jmp_buf* jb = 0; > > >>>>>>>>> EF1 a,b,c; > > >>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY1 > > >>>>>>>>> do stuff 1... > > >>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY2 > > >>>>>>>>> do stuff 2... > > >>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > // TRY3 > > >>>>>>>>> do stuff 3... > > >>>>>>>>> } > > >>>>>>>>> > > >>>>>>>>> (The actual syntactic and semantic correctness of this code > -- the > > >>>>>>>>> existance of the ternary operator, and that it only > evaluates one side > > >>>>>>>>> or the other, and that assignment is expression..I quite > like those > > >>>>>>>>> features....) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Still, something I can't pin down strikes me as too simple here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > > >>>>>>>>> additional progress, you only ever know the last place you > were in a > > >>>>>>>>> function. > > >>>>>>>>> That doesn't seem adequate. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> What if a function raises an exception, catches it within > itself, and > > >>>>>>>>> then raises something else, and then wants to catch that? > > >>>>>>>>> It won't know where to resume, right? It's just keep > longjmping to the > > >>>>>>>>> same place. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > "global unwind". > > >>>>>>>>> "local unwind" is like, "within the same functin", "global > unwind" is > > >>>>>>>>> across functions. > > >>>>>>>>> I think somehow that is related here. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> e.g. how would you ensure forward progress in this: > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> EXCEPTION E1; > > >>>>>>>>> EXCEPTION E2; > > >>>>>>>>> EXCEPTION E3; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> PROCEDURE F4() RAISES ANY = > > >>>>>>>>> CONST Function = "F4 "; > > >>>>>>>>> BEGIN > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> TRY > > >>>>>>>>> Put(Function & Int(Line())); NL(); > > >>>>>>>>> RAISE E1; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E2; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> RAISE E3; > > >>>>>>>>> END; > > >>>>>>>>> EXCEPT ELSE > > >>>>>>>>> END; > > >>>>>>>>> END F4; > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> I am OK with what you have currently: > > >>>>>>>>> > > >>>>>>>>> At each TRY: > > >>>>>>>>> > > >>>>>>>>> 1. Check if a corresponding alloca block has been allocated > by checking > > >>>>>>>>> if the corresponding local variable is NIL. > > >>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > > >>>>>>>>> 3. Execute the try block. > > >>>>>>>>> > > >>>>>>>>> As you say, alloca should turn into an inline operation using the > > >>>>>>>>> compiler's builtin implementation of alloca. > > >>>>>>>>> > > >>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > functions that use try. > > >>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > calls for n trys. > > >>>>>>>>> I thought it'd only be one call. I didn't realize our > implementation > > >>>>>>>>> is as poor as it is, since a better but still > > >>>>>>>>> portable implementation doesn't seem too too difficult. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > > >>>>>>>>> setjmp/alloca/pushframe per function? > > >>>>>>>>> Using a local integer to record the position within the function? > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> Or just give me a week or few to get stack walking working > and then > > >>>>>>>>> live the regression on other targets? > > >>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > certainly > > >>>>>>>>> possible; NT does have a decent runtime here..) > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> It *is* nice to not have have the frontend know about > jmpbuf size. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > used so easily. > > >>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > > >>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > > >>>>>>>>> > > >>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > guess your > > >>>>>>>>> point is, you'd rather have n locals, which the backend > automatically > > >>>>>>>>> merges, than n calls to alloca? > > >>>>>>>>> It's not a huge difference -- there are still going to be n > calls to > > >>>>>>>>> setjmp and n calls to pthread_getspecific. > > >>>>>>>>> The alloca calls will be dwarfed. > > >>>>>>>>> Code size will suffer. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And, even so, there are plenty of optimizations to be had, > even if > > >>>>>>>>> setjmp/pthread_getspecific is used. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - It could make a maximum of one call to > setjmp/pthread_getspecific > > >>>>>>>>> per function > > >>>>>>>>> - The calls to alloca could be merged. The frontend could > keep track > > >>>>>>>>> of how many calls it makes per function, > > >>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So, yes, given my current understanding, it is progress. > > >>>>>>>>> The target-dependence is not worth it, imho. > > >>>>>>>>> I'll still do some comparisons to release. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> I'll still be looking into using the gcc unwinder > relatively soon. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> Tony, um..well, um.. first, isn't that how it already > worked maybe? > > >>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > > >>>>>>>>> I'll do more testing. > > >>>>>>>>> > > >>>>>>>>> Yes, it did. I assume you simply have a local variable for > each TRY > > >>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> So the additional inefficiency is multiplied the same as > the rest of > > >>>>>>>>> the preexisting inefficiency. > > >>>>>>>>> And the preexisting inefficiency is way more than the increase. > > >>>>>>>>> > > >>>>>>>>> And second, either way, it could be better. > > >>>>>>>>> > > >>>>>>>>> Basically, the model should be, that if a function has any > try or lock, > > >>>>>>>>> it calls setjmp once. > > >>>>>>>>> And then, it should have one volatile integer, that in a sense > > >>>>>>>>> represents the line number. > > >>>>>>>>> But not really. It's like, every time you cross a TRY, the > integer is > > >>>>>>>>> incremented, every time you > > >>>>>>>>> cross a finally or unlock, the integer is decremented. Or > rather, the > > >>>>>>>>> value can be stored. > > >>>>>>>>> And then there is a maximum of one one handler per function, it > > >>>>>>>>> switches on the integer > > >>>>>>>>> to decide where it got into the function and what it should do. > > >>>>>>>>> > > >>>>>>>>> This is how other compilers work and it is a fairly simple > sensible approach. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> oops, that's not how I thought it worked. I'll do more > testing and fix > > >>>>>>>>> it -- check for NIL. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > But now you > > >>>>>>>>> are allocating on every TRY where previously the storage > was statically > > >>>>>>>>> allocated. Do you really think this is progress? > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> I've back with full keyboard if more explanation needed. > The diff is > > >>>>>>>>> actually fairly small to read. > > >>>>>>>>> I understand it is definitely less efficient, a few more > instructions > > >>>>>>>>> for every try/lock. > > >>>>>>>>> No extra function call, at least with gcc backend. > > >>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > the change > > >>>>>>>>> is written so that it should work > > >>>>>>>>> but I have to test it to be sure, will to roughly tonight. > And there > > >>>>>>>>> probably is a function call there. > > >>>>>>>>> > > >>>>>>>>> - Jay > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> From: jay.krell at cornell.edu > > >>>>>>>>> To: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > > >>>>>>>>> CC: m3commit at elegosoft.com > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> > > >>>>>>>>> I only have phone right now. I think it is fairly clear: > the jumpbuf in > > >>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > > >>>>>>>>> definitely a bit less efficient, but the significant advantage is > > >>>>>>>>> frontend no longer needs to know the size or alignment of a > jumpbuf. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> As well, there is no longer the problem regarding jumpbuf > aligned to > > >>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > alloca seems > > >>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > currently to see if > > >>>>>>>>> the problem is addressed there. > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> The inefficiency of course can be dramatically mitigated > via a stack > > >>>>>>>>> walker. I wanted to do this first though, while more > targets using > > >>>>>>>>> setjmp. > > >>>>>>>>> > > >>>>>>>>> - Jay/phone > > >>>>>>>>> > > >>>>>>>>> ________________________________ > > >>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > > >>>>>>>>> From: hosking at cs.purdue.edu > > >>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > > >>>>>>>>> > CC: jkrell at elego.de; m3commit at elegosoft.com > > >>>>>>>>> To: jay.krell at cornell.edu > > >>>>>>>>> > > >>>>>>>>> Can you provide a more descriptive checkin comment? I don't > know what > > >>>>>>>>> has been done here without diving into the diff. > > >>>>>>>>> > > >>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > Purdue University > > >>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > > >>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > > >>>>>>>>> > > >>>>>>>>> diff attached > > >>>>>>>>> > > >>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > > >>>>>>>>>> To: m3commit at elegosoft.com > > >>>>>>>>>> From: jkrell at elego.de > > >>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > > >>>>>>>>>> > > >>>>>>>>>> CVSROOT: /usr/cvs > > >>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > > >>>>>>>>>> > > >>>>>>>>>> Modified files: > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > > >>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > > >>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > >>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > > >>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > > >>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > > >>>>>>>>>> > > >>>>>>>>>> Log message: > > >>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > > >>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > > >>>>>>>>>> > > >>>>>>>>>> to allocate jmp_buf > > >>>>>>>>>> > > >>>>>>>>>> - eliminates a large swath of target-dependent code > > >>>>>>>>>> - allows for covering up the inability to declare > > >>>>>>>>>> types with alignment > 64 bits > > >>>>>>>>>> > > >>>>>>>>>> It is, granted, a little bit slower, in an already prety > slow path. > > >>>>>>>>>> Note that alloca isn't actually a function call, at least > with gcc backend. > > >>>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>> > > >> > > > > > > From hosking at cs.purdue.edu Fri Jan 7 08:25:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 7 Jan 2011 02:25:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> Message-ID: Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > Now, for all I know it is loading from a variable and the variable can change. > That's my uncertainty. > > > There is other similar code that I'm even less certain of, specifically: > > MODULE TryStmt; > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > (* declare and initialize the info record *) > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > CG.Type.Struct, 0, in_memory := TRUE, > up_level := FALSE, f := CG.Never); > CG.Load_nil (); > CG.Store_addr (info, M3RT.EA_exception); > > It could very well be that in: > > For i := 1 to 10 do try ... may or may not throw ... except else > > info needs to be nulled each time through. > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > Or maybe I can figure it out anyway from your clue. > (Or maybe I'll first go after Mika's two failing pieces of code..) > > Thanks, > - Jay > > > > > > ________________________________ >> Subject: Re: [M3commit] CVS Update: cm3 >> From: hosking at cs.purdue.edu >> Date: Thu, 6 Jan 2011 23:24:31 -0500 >> CC: m3commit at elegosoft.com >> To: jay.krell at cornell.edu >> >> Ah, yes, I see. You're right. >> The same proc is stored multiple times. >> We could indeed simply have a variable initialized once with the value >> of the proc. >> >> >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: >> >> I don't think so, but maybe. >> >> For i := 1 to 10 do try finally end >> >> will run that generated code 10 times but only the 1st is needed. In >> general? I not sure. >> >> Jay/phone >> >>> Subject: Re: [M3commit] CVS Update: cm3 >>> From: hosking at cs.purdue.edu >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 >>> CC: m3commit at elegosoft.com >>> To: jay.krell at cornell.edu >>> >>> You are confusing code emitted in the body of the loop with dynamic >> executions of that code. >>> CG calls are all compile-time generation of code. >>> >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: >>> >>>> >>>> If I have a try/finally or lock in a loop, those lines aren't going >> to guaranteeably store the same values each time? >>>> >>>> - Jay >>>> >>>> ---------------------------------------- >>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>> From: hosking at cs.purdue.edu >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 >>>>> CC: m3commit at elegosoft.com >>>>> To: jay.krell at cornell.edu >>>>> >>>>> In the code below there are no initializations. >>>>> >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: >>>>> >>>>>> >>>>>> ps: I think there other non-ideal initializations here. >>>>>> e.g. >>>>>> >>>>>> >>>>>> TryFinStmt.m3:Compile2 >>>>>> (* declare and initialize the info record *) >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, >> Target.Address.align, >>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>> up_level := FALSE, f := CG.Never); >>>>>> CG.Load_procedure (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); >>>>>> CG.Load_static_link (p.handler.cg_proc); >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); >>>>>> >>>>>> >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same >> initializations. >>>>>> Granted, this is non-stack-walker code. >>>>>> >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of >> m3front still.. >>>>>> >>>>>> - Jay >>>>>> >>>>>> ---------------------------------------- >>>>>>> From: jay.krell at cornell.edu >>>>>>> To: hosking at cs.purdue.edu >>>>>>> CC: m3commit at elegosoft.com >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 >>>>>>> >>>>>>> >>>>>>> The same way as before. I think this operates at too low a level >> to get any automatic initialization. >>>>>>> >>>>>>> TryStmt.m3 and TryFinStmt.m3: >>>>>>> >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, >> Target.Address.align, >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, >>>>>>> up_level := FALSE, f := CG.Never); >>>>>>> >>>>>>> I agree though, this might not be ideal. >>>>>>> >>>>>>> - Jay >>>>>>> >>>>>>> >>>>>>> ---------------------------------------- >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>> From: hosking at cs.purdue.edu >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 >>>>>>>> CC: m3commit at elegosoft.com >>>>>>>> To: jay.krell at cornell.edu >>>>>>>> >>>>>>>> I don't understand what you mean by "initializes to NIL". >>>>>>>> How are you creating the frame variable? >>>>>>>> If you do it properly the language semantics will cause it be >> initialized to NIL automatically. >>>>>>>> >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: >>>>>>>> >>>>>>>>> >>>>>>>>> Ok. >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? >>>>>>>>> >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* >> to correct, >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. >>>>>>>>> >>>>>>>>> >>>>>>>>> Index: misc/Marker.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v >>>>>>>>> retrieving revision 1.7 >>>>>>>>> diff -u -w -r1.7 Marker.m3 >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -233,6 +233,7 @@ >>>>>>>>> >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = >>>>>>>>> VAR new: BOOLEAN; >>>>>>>>> + label := CG.Next_label (); >>>>>>>>> BEGIN >>>>>>>>> (* int setjmp(void* ); *) >>>>>>>>> IF (setjmp = NIL) THEN >>>>>>>>> @@ -263,18 +264,25 @@ >>>>>>>>> Target.Word.cg_type, 0); >>>>>>>>> END; >>>>>>>>> >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) >>>>>>>>> + >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, >> CG.Maybe); >>>>>>>>> + >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); >>>>>>>>> CG.Pop_param (Target.Word.cg_type); >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> + (* END *) >>>>>>>>> + CG.Set_label (label); >>>>>>>>> >>>>>>>>> (* setmp(frame.jmpbuf) *) >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, >> Target.Address.align, >>>>>>>>> - Target.Address.cg_type); >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> CG.Pop_param (CG.Type.Addr); >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); >>>>>>>>> CG.If_true (handler, CG.Never); >>>>>>>>> cvs diff: Diffing stmts >>>>>>>>> Index: stmts/TryFinStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v >>>>>>>>> retrieving revision 1.6 >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -299,6 +299,10 @@ >>>>>>>>> CG.Load_nil (); >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> l := CG.Next_label (3); >>>>>>>>> CG.Set_label (l, barrier := TRUE); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); >>>>>>>>> Index: stmts/TryStmt.m3 >>>>>>>>> =================================================================== >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v >>>>>>>>> retrieving revision 1.3 >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 >>>>>>>>> @@ -10,7 +10,7 @@ >>>>>>>>> >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, >> Error, Marker; >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; >>>>>>>>> >>>>>>>>> TYPE >>>>>>>>> @@ -411,6 +411,10 @@ >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); >>>>>>>>> ***********************************************) >>>>>>>>> >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) >>>>>>>>> + CG.Load_nil (); >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); >>>>>>>>> + >>>>>>>>> IF (p.hasElse) THEN >>>>>>>>> Marker.PushTryElse (l, l+1, frame); >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); >>>>>>>>> >>>>>>>>> >>>>>>>>> The set_label before one of the PushEFrames could be moved >> down a bit, >>>>>>>>> to after the NIL initialization, and that'd fix some cases, >> but I think not all. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> - Jay >>>>>>>>> >>>>>>>>> >>>>>>>>> ---------------------------------------- >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 >>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>> >>>>>>>>>> At this point, we are trying to move away from the setjmp >> implementation to one that relies on unwind support, so I don't think >> the effort here is worthwhile. >>>>>>>>>> >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to >> return to. >>>>>>>>>>> There would also be a volatile local integer, that gets >> altered at certain points through the function. >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that >> integer to determine where to "really" go. >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a >> highly optimized frame based exception >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is >> reserved to be the head of the linked list of frames. >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> So the result is that a function with one or more tries, or >> one or more locals with destructors, >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the >> volatile local integer to indicate >>>>>>>>>>> where in the function it is. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> If NT/x86 were inefficient more analogous to current >> Modula-3, it'd link/unlink in FS:0 more often. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> It is more work through, granted, I can understand that. >>>>>>>>>>> And given that we have a much better option for many >> platforms, the payoff would be reduced. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. >> the previous approach. >>>>>>>>>>> It aligns more. So it is using more stack than the other way. >>>>>>>>>>> And it might pessimize codegen in other ways. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables >> merely describe, again, which >>>>>>>>>>> function/frame to return to, and that within the frame there >> is a local integer to determine >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a >> switch. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> - Jay >>>>>>>>>>> >>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per >> TRY scope, >>>>>>>>>>>> since they can be nested. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code >> allocates a >>>>>>>>>>>> local "EF1" for each try. >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, >> and store >>>>>>>>>>>> it in each EF* block? >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily >> figure out how >>>>>>>>>>>> to in the front end, I need to read it more. >>>>>>>>>>>> >>>>>>>>>>>> something like: >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 >> do stuff 3 >>>>>>>>>>>> END END END END F1; >>>>>>>>>>>> => >>>>>>>>>>>> >>>>>>>>>>>> void F1() >>>>>>>>>>>> { >>>>>>>>>>>> jmp_buf* jb = 0; >>>>>>>>>>>> EF1 a,b,c; >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY1 >>>>>>>>>>>> do stuff 1... >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY2 >>>>>>>>>>>> do stuff 2... >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); >> // TRY3 >>>>>>>>>>>> do stuff 3... >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code >> -- the >>>>>>>>>>>> existance of the ternary operator, and that it only >> evaluates one side >>>>>>>>>>>> or the other, and that assignment is expression..I quite >> like those >>>>>>>>>>>> features....) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of >>>>>>>>>>>> additional progress, you only ever know the last place you >> were in a >>>>>>>>>>>> function. >>>>>>>>>>>> That doesn't seem adequate. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> What if a function raises an exception, catches it within >> itself, and >>>>>>>>>>>> then raises something else, and then wants to catch that? >>>>>>>>>>>> It won't know where to resume, right? It's just keep >> longjmping to the >>>>>>>>>>>> same place. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and >> "global unwind". >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global >> unwind" is >>>>>>>>>>>> across functions. >>>>>>>>>>>> I think somehow that is related here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> e.g. how would you ensure forward progress in this: >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> EXCEPTION E1; >>>>>>>>>>>> EXCEPTION E2; >>>>>>>>>>>> EXCEPTION E3; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = >>>>>>>>>>>> CONST Function = "F4 "; >>>>>>>>>>>> BEGIN >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> TRY >>>>>>>>>>>> Put(Function & Int(Line())); NL(); >>>>>>>>>>>> RAISE E1; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E2; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> RAISE E3; >>>>>>>>>>>> END; >>>>>>>>>>>> EXCEPT ELSE >>>>>>>>>>>> END; >>>>>>>>>>>> END F4; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> I am OK with what you have currently: >>>>>>>>>>>> >>>>>>>>>>>> At each TRY: >>>>>>>>>>>> >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated >> by checking >>>>>>>>>>>> if the corresponding local variable is NIL. >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable >>>>>>>>>>>> 3. Execute the try block. >>>>>>>>>>>> >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the >>>>>>>>>>>> compiler's builtin implementation of alloca. >>>>>>>>>>>> >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in >> functions that use try. >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n >> calls for n trys. >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our >> implementation >>>>>>>>>>>> is as poor as it is, since a better but still >>>>>>>>>>>> portable implementation doesn't seem too too difficult. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one >>>>>>>>>>>> setjmp/alloca/pushframe per function? >>>>>>>>>>>> Using a local integer to record the position within the function? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Or just give me a week or few to get stack walking working >> and then >>>>>>>>>>>> live the regression on other targets? >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* >> certainly >>>>>>>>>>>> possible; NT does have a decent runtime here..) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> It *is* nice to not have have the frontend know about >> jmpbuf size. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be >> used so easily. >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 >>>>>>>>>>>> >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I >> guess your >>>>>>>>>>>> point is, you'd rather have n locals, which the backend >> automatically >>>>>>>>>>>> merges, than n calls to alloca? >>>>>>>>>>>> It's not a huge difference -- there are still going to be n >> calls to >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. >>>>>>>>>>>> The alloca calls will be dwarfed. >>>>>>>>>>>> Code size will suffer. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, >> even if >>>>>>>>>>>> setjmp/pthread_getspecific is used. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - It could make a maximum of one call to >> setjmp/pthread_getspecific >>>>>>>>>>>> per function >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could >> keep track >>>>>>>>>>>> of how many calls it makes per function, >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So, yes, given my current understanding, it is progress. >>>>>>>>>>>> The target-dependence is not worth it, imho. >>>>>>>>>>>> I'll still do some comparisons to release. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> I'll still be looking into using the gcc unwinder >> relatively soon. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already >> worked maybe? >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. >>>>>>>>>>>> I'll do more testing. >>>>>>>>>>>> >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for >> each TRY >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So the additional inefficiency is multiplied the same as >> the rest of >>>>>>>>>>>> the preexisting inefficiency. >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. >>>>>>>>>>>> >>>>>>>>>>>> And second, either way, it could be better. >>>>>>>>>>>> >>>>>>>>>>>> Basically, the model should be, that if a function has any >> try or lock, >>>>>>>>>>>> it calls setjmp once. >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense >>>>>>>>>>>> represents the line number. >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the >> integer is >>>>>>>>>>>> incremented, every time you >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or >> rather, the >>>>>>>>>>>> value can be stored. >>>>>>>>>>>> And then there is a maximum of one one handler per function, it >>>>>>>>>>>> switches on the integer >>>>>>>>>>>> to decide where it got into the function and what it should do. >>>>>>>>>>>> >>>>>>>>>>>> This is how other compilers work and it is a fairly simple >> sensible approach. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more >> testing and fix >>>>>>>>>>>> it -- check for NIL. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. >> But now you >>>>>>>>>>>> are allocating on every TRY where previously the storage >> was statically >>>>>>>>>>>> allocated. Do you really think this is progress? >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> I've back with full keyboard if more explanation needed. >> The diff is >>>>>>>>>>>> actually fairly small to read. >>>>>>>>>>>> I understand it is definitely less efficient, a few more >> instructions >>>>>>>>>>>> for every try/lock. >>>>>>>>>>>> No extra function call, at least with gcc backend. >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- >> the change >>>>>>>>>>>> is written so that it should work >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. >> And there >>>>>>>>>>>> probably is a function call there. >>>>>>>>>>>> >>>>>>>>>>>> - Jay >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> From: jay.krell at cornell.edu >>>>>>>>>>>> To: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 >>>>>>>>>>>> CC: m3commit at elegosoft.com >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: >> the jumpbuf in >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a >> jumpbuf. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf >> aligned to >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and >> alloca seems >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine >> currently to see if >>>>>>>>>>>> the problem is addressed there. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated >> via a stack >>>>>>>>>>>> walker. I wanted to do this first though, while more >> targets using >>>>>>>>>>>> setjmp. >>>>>>>>>>>> >>>>>>>>>>>> - Jay/phone >>>>>>>>>>>> >>>>>>>>>>>> ________________________________ >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 >>>>>>>>>>>> From: hosking at cs.purdue.edu >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 >>>>>>>>>>>> >> CC: jkrell at elego.de; m3commit at elegosoft.com >>>>>>>>>>>> To: jay.krell at cornell.edu >>>>>>>>>>>> >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't >> know what >>>>>>>>>>>> has been done here without diving into the diff. >>>>>>>>>>>> >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | >> Purdue University >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: >>>>>>>>>>>> >>>>>>>>>>>> diff attached >>>>>>>>>>>> >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 >>>>>>>>>>>>> To: m3commit at elegosoft.com >>>>>>>>>>>>> From: jkrell at elego.de >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 >>>>>>>>>>>>> >>>>>>>>>>>>> CVSROOT: /usr/cvs >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 >>>>>>>>>>>>> >>>>>>>>>>>>> Modified files: >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 >>>>>>>>>>>>> >>>>>>>>>>>>> Log message: >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) >>>>>>>>>>>>> >>>>>>>>>>>>> to allocate jmp_buf >>>>>>>>>>>>> >>>>>>>>>>>>> - eliminates a large swath of target-dependent code >>>>>>>>>>>>> - allows for covering up the inability to declare >>>>>>>>>>>>> types with alignment > 64 bits >>>>>>>>>>>>> >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety >> slow path. >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least >> with gcc backend. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From jay.krell at cornell.edu Fri Jan 7 11:46:05 2011 From: jay.krell at cornell.edu (Jay K) Date: Fri, 7 Jan 2011 10:46:05 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110105143455.087E22474003@birch.elegosoft.com>, , , , , , , , , , , , , <6E1D6FFD-3865-4F57-8918-CA752B08762D@cs.purdue.edu>, , <7C8B16A4-82E5-43C0-ABD5-55E3EAD80344@cs.purdue.edu>, , , <7A8D4DD7-B8B8-4541-A13F-4FD8C341617F@cs.purdue.edu>, , <115DE4C5-4B8C-44CE-BFBD-B8153064AC90@cs.purdue.edu>, , <760119C6-AAF1-408E-87B7-2E03118D977A@cs.purdue.edu>, , <50A26043-3A60-4E04-AA3D-6F63CCE11E10@cs.purdue.edu>, , , <2F1531C3-E5D3-4093-991D-FCE332C72AB6@cs.purdue.edu> , <6999D2FC-C251-4081-8CC0-CBB4641B7485@cs.purdue.edu> , Message-ID: > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. Correct. That part is easy to code and I have correct on my machine. What I don't have is doing the initialization, early enough in the generated code to be just once. ?> Perhaps that is not so easy, because you need to declare the variable in the outermost scope. Right. And still one per try. The current code is pretty bad, for try within a loop. I should also point out that the alloca approach is using a fair amount more stack. ?- the alloca is rounded up a lot for alignment ?- the extra pointer; but mainly I think the alignment Agreed, what I want to fix is more significant than the other "problem" I brought up, since one is allocating more and more stack, the other is not. One "problem" I just introduced, hasn't been around any amount of time, the other is long standing and nobody noticed. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Fri, 7 Jan 2011 02:25:30 -0500 > CC: m3commit at elegosoft.com > To: jay.krell at cornell.edu > > Doesn't the code you quote need to store NIL so that we know whether the TRY generated an exception or not? > > Also, you don't need actually to remove alloca from loops do you? You could just check for NIL each time through and alloca only if NIL. > My suggestion was that you could cause the alloca to run once to initialize each variable in the outer scope of the function using the existing Variable.T initialization support. Perhaps that is not so easy, because you need to declare the variable in the outermost scope. > > On Jan 7, 2011, at 12:38 AM, Jay K wrote: > > > > > Now, for all I know it is loading from a variable and the variable can change. > > That's my uncertainty. > > > > > > There is other similar code that I'm even less certain of, specifically: > > > > MODULE TryStmt; > > > > PROCEDURE Compile1 (p: P): Stmt.Outcomes = > > > > (* declare and initialize the info record *) > > info := CG.Declare_local (M3ID.NoID, M3RT.EA_SIZE, Target.Address.align, > > CG.Type.Struct, 0, in_memory := TRUE, > > up_level := FALSE, f := CG.Never); > > CG.Load_nil (); > > CG.Store_addr (info, M3RT.EA_exception); > > > > It could very well be that in: > > > > For i := 1 to 10 do try ... may or may not throw ... except else > > > > info needs to be nulled each time through. > > > > If you fixup this stuff, I'll know more easily how to remove the allocas from loops. > > Or maybe I can figure it out anyway from your clue. > > (Or maybe I'll first go after Mika's two failing pieces of code..) > > > > Thanks, > > - Jay > > > > > > > > > > > > ________________________________ > >> Subject: Re: [M3commit] CVS Update: cm3 > >> From: hosking at cs.purdue.edu > >> Date: Thu, 6 Jan 2011 23:24:31 -0500 > >> CC: m3commit at elegosoft.com > >> To: jay.krell at cornell.edu > >> > >> Ah, yes, I see. You're right. > >> The same proc is stored multiple times. > >> We could indeed simply have a variable initialized once with the value > >> of the proc. > >> > >> > >> On Jan 6, 2011, at 11:08 PM, Jay K wrote: > >> > >> I don't think so, but maybe. > >> > >> For i := 1 to 10 do try finally end > >> > >> will run that generated code 10 times but only the 1st is needed. In > >> general? I not sure. > >> > >> Jay/phone > >> > >>> Subject: Re: [M3commit] CVS Update: cm3 > >>> From: hosking at cs.purdue.edu > >>> Date: Thu, 6 Jan 2011 16:56:48 -0500 > >>> CC: m3commit at elegosoft.com > >>> To: jay.krell at cornell.edu > >>> > >>> You are confusing code emitted in the body of the loop with dynamic > >> executions of that code. > >>> CG calls are all compile-time generation of code. > >>> > >>> On Jan 6, 2011, at 4:17 PM, Jay K wrote: > >>> > >>>> > >>>> If I have a try/finally or lock in a loop, those lines aren't going > >> to guaranteeably store the same values each time? > >>>> > >>>> - Jay > >>>> > >>>> ---------------------------------------- > >>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>> From: hosking at cs.purdue.edu > >>>>> Date: Thu, 6 Jan 2011 16:00:08 -0500 > >>>>> CC: m3commit at elegosoft.com > >>>>> To: jay.krell at cornell.edu > >>>>> > >>>>> In the code below there are no initializations. > >>>>> > >>>>> On Jan 6, 2011, at 3:51 PM, Jay K wrote: > >>>>> > >>>>>> > >>>>>> ps: I think there other non-ideal initializations here. > >>>>>> e.g. > >>>>>> > >>>>>> > >>>>>> TryFinStmt.m3:Compile2 > >>>>>> (* declare and initialize the info record *) > >>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF2_SIZE, > >> Target.Address.align, > >>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>> up_level := FALSE, f := CG.Never); > >>>>>> CG.Load_procedure (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_handler); > >>>>>> CG.Load_static_link (p.handler.cg_proc); > >>>>>> CG.Store_addr (frame, M3RT.EF2_frame); > >>>>>> > >>>>>> > >>>>>> Putting TRY/LOCK in loops probably repeatedly does the same > >> initializations. > >>>>>> Granted, this is non-stack-walker code. > >>>>>> > >>>>>> Seems all bit a suspicious to me, though I'm pretty ignorant of > >> m3front still.. > >>>>>> > >>>>>> - Jay > >>>>>> > >>>>>> ---------------------------------------- > >>>>>>> From: jay.krell at cornell.edu > >>>>>>> To: hosking at cs.purdue.edu > >>>>>>> CC: m3commit at elegosoft.com > >>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>> Date: Thu, 6 Jan 2011 20:48:56 +0000 > >>>>>>> > >>>>>>> > >>>>>>> The same way as before. I think this operates at too low a level > >> to get any automatic initialization. > >>>>>>> > >>>>>>> TryStmt.m3 and TryFinStmt.m3: > >>>>>>> > >>>>>>> frame := CG.Declare_local (M3ID.NoID, M3RT.EF1_SIZE, > >> Target.Address.align, > >>>>>>> CG.Type.Struct, 0, in_memory := TRUE, > >>>>>>> up_level := FALSE, f := CG.Never); > >>>>>>> > >>>>>>> I agree though, this might not be ideal. > >>>>>>> > >>>>>>> - Jay > >>>>>>> > >>>>>>> > >>>>>>> ---------------------------------------- > >>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>> Date: Thu, 6 Jan 2011 15:42:33 -0500 > >>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>> To: jay.krell at cornell.edu > >>>>>>>> > >>>>>>>> I don't understand what you mean by "initializes to NIL". > >>>>>>>> How are you creating the frame variable? > >>>>>>>> If you do it properly the language semantics will cause it be > >> initialized to NIL automatically. > >>>>>>>> > >>>>>>>> On Jan 6, 2011, at 3:33 PM, Jay K wrote: > >>>>>>>> > >>>>>>>>> > >>>>>>>>> Ok. > >>>>>>>>> Do you know where to initialize the jmpbuf to NIL? > >>>>>>>>> > >>>>>>>>> I have a diff that "works" (ie: doesn't crash) and is *close* > >> to correct, > >>>>>>>>> it checks for NIL and branches around the alloca for non-NIL, but it > >>>>>>>>> also initializes to NIL repeatedly, so no change effectively. > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> Index: misc/Marker.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v > >>>>>>>>> retrieving revision 1.7 > >>>>>>>>> diff -u -w -r1.7 Marker.m3 > >>>>>>>>> --- misc/Marker.m3 5 Jan 2011 14:34:54 -0000 1.7 > >>>>>>>>> +++ misc/Marker.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -233,6 +233,7 @@ > >>>>>>>>> > >>>>>>>>> PROCEDURE CaptureState (frame: CG.Var; handler: CG.Label) = > >>>>>>>>> VAR new: BOOLEAN; > >>>>>>>>> + label := CG.Next_label (); > >>>>>>>>> BEGIN > >>>>>>>>> (* int setjmp(void* ); *) > >>>>>>>>> IF (setjmp = NIL) THEN > >>>>>>>>> @@ -263,18 +264,25 @@ > >>>>>>>>> Target.Word.cg_type, 0); > >>>>>>>>> END; > >>>>>>>>> > >>>>>>>>> + (* IF frame.jmpbuf = NIL THEN *) > >>>>>>>>> + > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + CG.If_compare (Target.Address.cg_type, CG.Cmp.NE, label, > >> CG.Maybe); > >>>>>>>>> + > >>>>>>>>> (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *) > >>>>>>>>> CG.Start_call_direct (alloca, 0, Target.Address.cg_type); > >>>>>>>>> CG.Load_int (Target.Word.cg_type, Jumpbuf_size); > >>>>>>>>> CG.Pop_param (Target.Word.cg_type); > >>>>>>>>> CG.Call_direct (alloca, Target.Address.cg_type); > >>>>>>>>> - CG.Store (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> + (* END *) > >>>>>>>>> + CG.Set_label (label); > >>>>>>>>> > >>>>>>>>> (* setmp(frame.jmpbuf) *) > >>>>>>>>> CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type); > >>>>>>>>> - CG.Load (frame, M3RT.EF1_jmpbuf, Target.Address.size, > >> Target.Address.align, > >>>>>>>>> - Target.Address.cg_type); > >>>>>>>>> + CG.Load_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> CG.Pop_param (CG.Type.Addr); > >>>>>>>>> CG.Call_direct (setjmp, Target.Integer.cg_type); > >>>>>>>>> CG.If_true (handler, CG.Never); > >>>>>>>>> cvs diff: Diffing stmts > >>>>>>>>> Index: stmts/TryFinStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v > >>>>>>>>> retrieving revision 1.6 > >>>>>>>>> diff -u -w -r1.6 TryFinStmt.m3 > >>>>>>>>> --- stmts/TryFinStmt.m3 5 Jan 2011 14:34:54 -0000 1.6 > >>>>>>>>> +++ stmts/TryFinStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -299,6 +299,10 @@ > >>>>>>>>> CG.Load_nil (); > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_info + M3RT.EA_exception); > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> l := CG.Next_label (3); > >>>>>>>>> CG.Set_label (l, barrier := TRUE); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.Finally); > >>>>>>>>> Index: stmts/TryStmt.m3 > >>>>>>>>> =================================================================== > >>>>>>>>> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v > >>>>>>>>> retrieving revision 1.3 > >>>>>>>>> diff -u -w -r1.3 TryStmt.m3 > >>>>>>>>> --- stmts/TryStmt.m3 5 Jan 2011 14:34:54 -0000 1.3 > >>>>>>>>> +++ stmts/TryStmt.m3 6 Jan 2011 20:32:00 -0000 > >>>>>>>>> @@ -10,7 +10,7 @@ > >>>>>>>>> > >>>>>>>>> IMPORT M3, M3ID, CG, Variable, Scope, Exceptionz, Value, > >> Error, Marker; > >>>>>>>>> IMPORT Type, Stmt, StmtRep, TryFinStmt, Token; > >>>>>>>>> -IMPORT Scanner, ESet, Target, M3RT, Tracer; > >>>>>>>>> +IMPORT Scanner, ESet, Target, M3RT, Tracer, IO; > >>>>>>>>> FROM Scanner IMPORT Match, MatchID, GetToken, Fail, cur; > >>>>>>>>> > >>>>>>>>> TYPE > >>>>>>>>> @@ -411,6 +411,10 @@ > >>>>>>>>> CG.Store_addr (frame, M3RT.EF1_exception); > >>>>>>>>> ***********************************************) > >>>>>>>>> > >>>>>>>>> + (* no jmpbuf yet (avoid repeated alloca in try within loop) *) > >>>>>>>>> + CG.Load_nil (); > >>>>>>>>> + CG.Store_addr (frame, M3RT.EF1_jmpbuf); > >>>>>>>>> + > >>>>>>>>> IF (p.hasElse) THEN > >>>>>>>>> Marker.PushTryElse (l, l+1, frame); > >>>>>>>>> Marker.PushFrame (frame, M3RT.HandlerClass.ExceptElse); > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> The set_label before one of the PushEFrames could be moved > >> down a bit, > >>>>>>>>> to after the NIL initialization, and that'd fix some cases, > >> but I think not all. > >>>>>>>>> > >>>>>>>>> Thanks, > >>>>>>>>> - Jay > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> ---------------------------------------- > >>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>> Date: Thu, 6 Jan 2011 14:11:04 -0500 > >>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>> > >>>>>>>>>> At this point, we are trying to move away from the setjmp > >> implementation to one that relies on unwind support, so I don't think > >> the effort here is worthwhile. > >>>>>>>>>> > >>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> On Jan 6, 2011, at 2:00 PM, Jay K wrote: > >>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I believe you can, but it'd take significant work in the frontend. > >>>>>>>>>>> The jmpbuf should identify merely which procedure/frame to > >> return to. > >>>>>>>>>>> There would also be a volatile local integer, that gets > >> altered at certain points through the function. > >>>>>>>>>>> When setjmp returns exceptionally, you'd switch on that > >> integer to determine where to "really" go. > >>>>>>>>>>> This is analogous to how other systems work -- NT/x86 has a > >> highly optimized frame based exception > >>>>>>>>>>> handling. Instead of a generic thread local, FS:0 is > >> reserved to be the head of the linked list of frames. > >>>>>>>>>>> Instead of setjmp, the compiler pessimizes appropriately. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> So the result is that a function with one or more tries, or > >> one or more locals with destructors, > >>>>>>>>>>> puts one node on the FS:0 list, and then mucks with the > >> volatile local integer to indicate > >>>>>>>>>>> where in the function it is. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> If NT/x86 were inefficient more analogous to current > >> Modula-3, it'd link/unlink in FS:0 more often. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> It is more work through, granted, I can understand that. > >>>>>>>>>>> And given that we have a much better option for many > >> platforms, the payoff would be reduced. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> Anyway, I'm trying what you say, like for TRY within a loop. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> I should point out that alloca has an extra inefficiency vs. > >> the previous approach. > >>>>>>>>>>> It aligns more. So it is using more stack than the other way. > >>>>>>>>>>> And it might pessimize codegen in other ways. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> The gcc code appears somewhat similar..I think the tables > >> merely describe, again, which > >>>>>>>>>>> function/frame to return to, and that within the frame there > >> is a local integer to determine > >>>>>>>>>>> more precisely what to do. I'm not sure. I saw mention of a > >> switch. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> - Jay > >>>>>>>>>>> > >>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 13:52:42 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> You can't have one jmpbuf per procedure. You need one per > >> TRY scope, > >>>>>>>>>>>> since they can be nested. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 11:35 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Hm. How do I single instance the "EF1"? The current code > >> allocates a > >>>>>>>>>>>> local "EF1" for each try. > >>>>>>>>>>>> I guess, really, it is EF1, EF2, etc. > >>>>>>>>>>>> So there should be a separate local for the jmpbuf pointer, > >> and store > >>>>>>>>>>>> it in each EF* block? > >>>>>>>>>>>> How do I make just one jmpbuf pointer? I couldn't easily > >> figure out how > >>>>>>>>>>>> to in the front end, I need to read it more. > >>>>>>>>>>>> > >>>>>>>>>>>> something like: > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F1() = BEGIN TRY1 do stuff1 TRY2 do stuff 2 TRY3 > >> do stuff 3 > >>>>>>>>>>>> END END END END F1; > >>>>>>>>>>>> => > >>>>>>>>>>>> > >>>>>>>>>>>> void F1() > >>>>>>>>>>>> { > >>>>>>>>>>>> jmp_buf* jb = 0; > >>>>>>>>>>>> EF1 a,b,c; > >>>>>>>>>>>> setjmp(a.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY1 > >>>>>>>>>>>> do stuff 1... > >>>>>>>>>>>> setjmp(b.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY2 > >>>>>>>>>>>> do stuff 2... > >>>>>>>>>>>> setjmp(c.jmpbuf = jb ? jb : (jb = alloca(sizeof(jmp_buf))); > >> // TRY3 > >>>>>>>>>>>> do stuff 3... > >>>>>>>>>>>> } > >>>>>>>>>>>> > >>>>>>>>>>>> (The actual syntactic and semantic correctness of this code > >> -- the > >>>>>>>>>>>> existance of the ternary operator, and that it only > >> evaluates one side > >>>>>>>>>>>> or the other, and that assignment is expression..I quite > >> like those > >>>>>>>>>>>> features....) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Still, something I can't pin down strikes me as too simple here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> If there is just one setjmp, and no integer(s) to keep track of > >>>>>>>>>>>> additional progress, you only ever know the last place you > >> were in a > >>>>>>>>>>>> function. > >>>>>>>>>>>> That doesn't seem adequate. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> What if a function raises an exception, catches it within > >> itself, and > >>>>>>>>>>>> then raises something else, and then wants to catch that? > >>>>>>>>>>>> It won't know where to resume, right? It's just keep > >> longjmping to the > >>>>>>>>>>>> same place. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> In the Visual C++ runtime, there is "local unwind" and > >> "global unwind". > >>>>>>>>>>>> "local unwind" is like, "within the same functin", "global > >> unwind" is > >>>>>>>>>>>> across functions. > >>>>>>>>>>>> I think somehow that is related here. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> e.g. how would you ensure forward progress in this: > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> EXCEPTION E1; > >>>>>>>>>>>> EXCEPTION E2; > >>>>>>>>>>>> EXCEPTION E3; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> PROCEDURE F4() RAISES ANY = > >>>>>>>>>>>> CONST Function = "F4 "; > >>>>>>>>>>>> BEGIN > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> TRY > >>>>>>>>>>>> Put(Function & Int(Line())); NL(); > >>>>>>>>>>>> RAISE E1; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E2; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> RAISE E3; > >>>>>>>>>>>> END; > >>>>>>>>>>>> EXCEPT ELSE > >>>>>>>>>>>> END; > >>>>>>>>>>>> END F4; > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Oddly in my test p251, the stack depth is not increased by TRY. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 09:22:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> I am OK with what you have currently: > >>>>>>>>>>>> > >>>>>>>>>>>> At each TRY: > >>>>>>>>>>>> > >>>>>>>>>>>> 1. Check if a corresponding alloca block has been allocated > >> by checking > >>>>>>>>>>>> if the corresponding local variable is NIL. > >>>>>>>>>>>> 2. If not, then alloca and save its pointer in the local variable > >>>>>>>>>>>> 3. Execute the try block. > >>>>>>>>>>>> > >>>>>>>>>>>> As you say, alloca should turn into an inline operation using the > >>>>>>>>>>>> compiler's builtin implementation of alloca. > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 6, 2011, at 1:02 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Indeed. Unoptimized code size does suffer a lot, in > >> functions that use try. > >>>>>>>>>>>> Calling alloca, unoptimized, isn't small, and this adds n > >> calls for n trys. > >>>>>>>>>>>> I thought it'd only be one call. I didn't realize our > >> implementation > >>>>>>>>>>>> is as poor as it is, since a better but still > >>>>>>>>>>>> portable implementation doesn't seem too too difficult. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Can we maybe do the optimizations I indicate -- no more than one > >>>>>>>>>>>> setjmp/alloca/pushframe per function? > >>>>>>>>>>>> Using a local integer to record the position within the function? > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> Or just give me a week or few to get stack walking working > >> and then > >>>>>>>>>>>> live the regression on other targets? > >>>>>>>>>>>> (NT386 isn't likely to get stack walking, though it *is* > >> certainly > >>>>>>>>>>>> possible; NT does have a decent runtime here..) > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> It *is* nice to not have have the frontend know about > >> jmpbuf size. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I looked into the "builtin_setjmp" stuff, but it can't be > >> used so easily. > >>>>>>>>>>>> It doesn't work for intra-function jumps, only inter-function. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: RE: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> Date: Thu, 6 Jan 2011 04:52:33 +0000 > >>>>>>>>>>>> > >>>>>>>>>>>> Ah..I'm doing more comparisons of release vs. head...but..I > >> guess your > >>>>>>>>>>>> point is, you'd rather have n locals, which the backend > >> automatically > >>>>>>>>>>>> merges, than n calls to alloca? > >>>>>>>>>>>> It's not a huge difference -- there are still going to be n > >> calls to > >>>>>>>>>>>> setjmp and n calls to pthread_getspecific. > >>>>>>>>>>>> The alloca calls will be dwarfed. > >>>>>>>>>>>> Code size will suffer. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> And, even so, there are plenty of optimizations to be had, > >> even if > >>>>>>>>>>>> setjmp/pthread_getspecific is used. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - It could make a maximum of one call to > >> setjmp/pthread_getspecific > >>>>>>>>>>>> per function > >>>>>>>>>>>> - The calls to alloca could be merged. The frontend could > >> keep track > >>>>>>>>>>>> of how many calls it makes per function, > >>>>>>>>>>>> issue a multiplication, and offset each jmpbuf. It is a tradeoff. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So, yes, given my current understanding, it is progress. > >>>>>>>>>>>> The target-dependence is not worth it, imho. > >>>>>>>>>>>> I'll still do some comparisons to release. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> I'll still be looking into using the gcc unwinder > >> relatively soon. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 21:14:17 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:08 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> Tony, um..well, um.. first, isn't that how it already > >> worked maybe? > >>>>>>>>>>>> Declaring a new local EF1 for each TRY? It looks like it. > >>>>>>>>>>>> I'll do more testing. > >>>>>>>>>>>> > >>>>>>>>>>>> Yes, it did. I assume you simply have a local variable for > >> each TRY > >>>>>>>>>>>> block that is a pointer now instead of a jmp_buf. Should be OK. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> So the additional inefficiency is multiplied the same as > >> the rest of > >>>>>>>>>>>> the preexisting inefficiency. > >>>>>>>>>>>> And the preexisting inefficiency is way more than the increase. > >>>>>>>>>>>> > >>>>>>>>>>>> And second, either way, it could be better. > >>>>>>>>>>>> > >>>>>>>>>>>> Basically, the model should be, that if a function has any > >> try or lock, > >>>>>>>>>>>> it calls setjmp once. > >>>>>>>>>>>> And then, it should have one volatile integer, that in a sense > >>>>>>>>>>>> represents the line number. > >>>>>>>>>>>> But not really. It's like, every time you cross a TRY, the > >> integer is > >>>>>>>>>>>> incremented, every time you > >>>>>>>>>>>> cross a finally or unlock, the integer is decremented. Or > >> rather, the > >>>>>>>>>>>> value can be stored. > >>>>>>>>>>>> And then there is a maximum of one one handler per function, it > >>>>>>>>>>>> switches on the integer > >>>>>>>>>>>> to decide where it got into the function and what it should do. > >>>>>>>>>>>> > >>>>>>>>>>>> This is how other compilers work and it is a fairly simple > >> sensible approach. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:49:24 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Note that you need a different jmpbuf for each nested TRY! > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 8:33 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> oops, that's not how I thought it worked. I'll do more > >> testing and fix > >>>>>>>>>>>> it -- check for NIL. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:23:09 -0500 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Ah, yes, I guess you need a different jmpbuf for each TRY. > >> But now you > >>>>>>>>>>>> are allocating on every TRY where previously the storage > >> was statically > >>>>>>>>>>>> allocated. Do you really think this is progress? > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 5:40 PM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> I've back with full keyboard if more explanation needed. > >> The diff is > >>>>>>>>>>>> actually fairly small to read. > >>>>>>>>>>>> I understand it is definitely less efficient, a few more > >> instructions > >>>>>>>>>>>> for every try/lock. > >>>>>>>>>>>> No extra function call, at least with gcc backend. > >>>>>>>>>>>> I haven't tested NT386 yet. Odds are so/so that it works -- > >> the change > >>>>>>>>>>>> is written so that it should work > >>>>>>>>>>>> but I have to test it to be sure, will to roughly tonight. > >> And there > >>>>>>>>>>>> probably is a function call there. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> From: jay.krell at cornell.edu > >>>>>>>>>>>> To: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 20:44:08 +0000 > >>>>>>>>>>>> CC: m3commit at elegosoft.com > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> > >>>>>>>>>>>> I only have phone right now. I think it is fairly clear: > >> the jumpbuf in > >>>>>>>>>>>> EF1 is now allocated with alloca, and a pointer stored. It is > >>>>>>>>>>>> definitely a bit less efficient, but the significant advantage is > >>>>>>>>>>>> frontend no longer needs to know the size or alignment of a > >> jumpbuf. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> As well, there is no longer the problem regarding jumpbuf > >> aligned to > >>>>>>>>>>>> more than 64 bits. I at least checked on Linux/PowerPC and > >> alloca seems > >>>>>>>>>>>> to align to 16 bytes. I don't have an HPUX machine > >> currently to see if > >>>>>>>>>>>> the problem is addressed there. > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> The inefficiency of course can be dramatically mitigated > >> via a stack > >>>>>>>>>>>> walker. I wanted to do this first though, while more > >> targets using > >>>>>>>>>>>> setjmp. > >>>>>>>>>>>> > >>>>>>>>>>>> - Jay/phone > >>>>>>>>>>>> > >>>>>>>>>>>> ________________________________ > >>>>>>>>>>>> Subject: Re: [M3commit] CVS Update: cm3 > >>>>>>>>>>>> From: hosking at cs.purdue.edu > >>>>>>>>>>>> Date: Wed, 5 Jan 2011 13:35:59 -0500 > >>>>>>>>>>>> > >> CC: jkrell at elego.de; m3commit at elegosoft.com > >>>>>>>>>>>> To: jay.krell at cornell.edu > >>>>>>>>>>>> > >>>>>>>>>>>> Can you provide a more descriptive checkin comment? I don't > >> know what > >>>>>>>>>>>> has been done here without diving into the diff. > >>>>>>>>>>>> > >>>>>>>>>>>> Antony Hosking | Associate Professor | Computer Science | > >> Purdue University > >>>>>>>>>>>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>>>>>>>>>>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Jan 5, 2011, at 9:37 AM, Jay K wrote: > >>>>>>>>>>>> > >>>>>>>>>>>> diff attached > >>>>>>>>>>>> > >>>>>>>>>>>>> Date: Wed, 5 Jan 2011 15:34:55 +0000 > >>>>>>>>>>>>> To: m3commit at elegosoft.com > >>>>>>>>>>>>> From: jkrell at elego.de > >>>>>>>>>>>>> Subject: [M3commit] CVS Update: cm3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> CVSROOT: /usr/cvs > >>>>>>>>>>>>> Changes by: jkrell at birch. 11/01/05 15:34:55 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Modified files: > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/Common/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_CYGWIN/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_MINGW/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/I386_NT/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/C/NT386/: Csetjmp.i3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/runtime/ex_frame/: RTExFrame.m3 > >>>>>>>>>>>>> cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c > >>>>>>>>>>>>> cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/misc/: Marker.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3front/src/stmts/: TryFinStmt.m3 TryStmt.m3 > >>>>>>>>>>>>> cm3/m3-sys/m3middle/src/: M3RT.i3 M3RT.m3 Target.i3 Target.m3 > >>>>>>>>>>>>> > >>>>>>>>>>>>> Log message: > >>>>>>>>>>>>> use: extern INTEGER Csetjmp__Jumpbuf_size /* = sizeof(jmp_buf); > >>>>>>>>>>>>> alloca(Csetjmp__Jumpbuf_size) > >>>>>>>>>>>>> > >>>>>>>>>>>>> to allocate jmp_buf > >>>>>>>>>>>>> > >>>>>>>>>>>>> - eliminates a large swath of target-dependent code > >>>>>>>>>>>>> - allows for covering up the inability to declare > >>>>>>>>>>>>> types with alignment > 64 bits > >>>>>>>>>>>>> > >>>>>>>>>>>>> It is, granted, a little bit slower, in an already prety > >> slow path. > >>>>>>>>>>>>> Note that alloca isn't actually a function call, at least > >> with gcc backend. From jkrell at elego.de Fri Jan 7 21:26:44 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:26:44 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202644.D50812474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:26:44 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Fri Jan 7 21:29:00 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 7 Jan 2011 21:29:00 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110107202900.167F32474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/07 21:29:00 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: a little more debuggability From jkrell at elego.de Sat Jan 8 05:57:15 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 5:57:15 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108045715.A9F19CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 05:57:15 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: comments only: "won" => "won the race"; "!" => "." From jkrell at elego.de Sat Jan 8 06:01:20 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:01:20 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108050121.3B57FCC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:01:20 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: leave initMu before calling RegisterFinalCleanup, to avoid deadlock with AtForkPrepare From jay.krell at cornell.edu Sat Jan 8 06:05:19 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 05:05:19 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.245 diff -u -r1.245 ThreadPThread.m3 --- ThreadPThread.m3??? 8 Jan 2011 04:57:15 -0000??? 1.245 +++ ThreadPThread.m3??? 8 Jan 2011 04:58:57 -0000 @@ -96,6 +96,7 @@ ?PROCEDURE InitMutex (VAR m: pthread_mutex_t; root: REFANY; ????????????????????? Clean: PROCEDURE(root: REFANY)) = ?? VAR mutex := pthread_mutex_new(); +????? register := FALSE; ?? BEGIN ???? TRY ?????? WITH r = pthread_mutex_lock(initMu) DO <*ASSERT r=0*> END; @@ -103,13 +104,24 @@ ?????? IF m # NIL THEN RETURN END; ?????? (* We won the race, but we might have failed to allocate. *) ?????? IF mutex = NIL THEN RTE.Raise (RTE.T.OutOfMemory) END; -????? RTHeapRep.RegisterFinalCleanup (root, Clean); ?????? m := mutex; ?????? mutex := NIL; +????? register := TRUE; ???? FINALLY ?????? WITH r = pthread_mutex_unlock(initMu) DO <*ASSERT r=0*> END; ?????? pthread_mutex_delete(mutex); ???? END; +??? IF register THEN +????? (* RegisterFinalCleanup serializes itself using RTOS.LockHeap. +???????? Call it outside initMu to avoid deadlock with AtForkPrepare. +???????? Register can happen outside a lock because the root is yet +???????? alive and therefore will not be collected between pthread_mutex_new +???????? and RegisterFinalCleanup. We are careful to only RegisterFinalCleanup +???????? once -- not in the lost race cases -- though it does not clearly +???????? matter. +?????? *) +????? RTHeapRep.RegisterFinalCleanup (root, Clean); +??? END; ?? END InitMutex; ? ?PROCEDURE LockMutex (m: Mutex) = I wonder if we should dispense with initMu and eagerly initialize all mutexes. ?- Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 06:01:20 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare > From jkrell at elego.de Sat Jan 8 06:22:51 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 6:22:51 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108052251.34065CC365@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 06:22:51 Modified files: cm3/m3-sys/cminstall/src/config-no-install/: I386.common Log message: -march=i586 => -march=i686 to fix test case p249: ../Main.m3: In function 'Main__DumpMatching__DumpOne': ../Main.m3:19:0: error: unable to find a register to spill in class 'CREG' ../Main.m3:19:0: error: this is the insn: (insn 5 4 6 2 ../Main.m3:16 (parallel [ (set (reg:SI 0 ax [65]) (const_int 0 [0x0])) (set (reg:SI 5 di [63]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg:SI 5 di [63]))) (set (reg/f:SI 4 si [64]) (plus:SI (ashift:SI (reg:SI 0 ax [65]) (const_int 2 [0x2])) (reg/f:SI 16 argp))) (set (mem/s/c:BLK (reg:SI 5 di [63]) [0 trade+0 S24 A64]) (mem/s/c:BLK (reg/f:SI 16 argp) [0 trade+0 S24 A32])) (use (reg:SI 0 ax [65])) ]) 838 {*rep_movsi} (expr_list:REG_UNUSED (reg:SI 0 ax [65]) (expr_list:REG_UNUSED (reg/f:SI 4 si [64]) (expr_list:REG_UNUSED (reg:SI 5 di [63]) (nil))))) ../Main.m3:19:0: internal compiler error: in spill_failure, at reload1.c:2163 probably merits further investigation From jkrell at elego.de Sat Jan 8 09:15:22 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:15:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108081522.7A4C12474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:15:21 Modified files: cm3/m3-sys/m3tests/src/p2/p250/: Main.m3 Log message: more LONGINT subrange problems, this now has 3 internal codegen errors, due to stack type and expected type mismatches From jkrell at elego.de Sat Jan 8 09:37:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:37:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083705.7F8E22474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:37:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: make errors visible on stdout or stderr, much better now we get: jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 --- building in I386_DARWIN --- new source -> compiling Main.m3 "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) 4 errors encountered (this should probably say 3) compilation failed => not building program "pgm" Fatal Error: package build failed From jkrell at elego.de Sat Jan 8 09:39:05 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083905.9D49E2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:05 Modified files: cm3/m3-sys/m3middle/src/: M3CG_Check.m3 Log message: put back 'self' as 'u' in PutErr, for smaller historical diff From jkrell at elego.de Sat Jan 8 09:39:34 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 8 Jan 2011 9:39:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110108083934.F0E71CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/08 09:39:34 Modified files: cm3/m3-sys/m3middle/src/: M3RT.m3 Log message: remove unused RoundUp function From jay.krell at cornell.edu Sat Jan 8 09:38:09 2011 From: jay.krell at cornell.edu (Jay K) Date: Sat, 8 Jan 2011 08:38:09 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108083705.7F8E22474003@birch.elegosoft.com> References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: Index: src/M3CG_Check.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v retrieving revision 1.13 diff -u -r1.13 M3CG_Check.m3 --- src/M3CG_Check.m3??? 1 Nov 2010 09:37:23 -0000??? 1.13 +++ src/M3CG_Check.m3??? 8 Jan 2011 08:36:01 -0000 @@ -57,6 +57,7 @@ ???????? s_push (t: Type) := Stack_Push; ???????? s_repush () := Stack_Repush; ???????? s_empty () := Stack_Empty; +??????? PutErr (a, b, c: TEXT) := PutErr; ?????? OVERRIDES ???????? set_error_handler := set_error_handler; ???????? begin_unit := begin_unit; @@ -185,10 +186,11 @@ ? ?(*--------------------------------------------------------- low level I/O ---*) ? -PROCEDURE PutErr (u: U;? a, b, c: TEXT := NIL) = +PROCEDURE PutErr (self: U;? a, b, c: TEXT := NIL) = ?? BEGIN -??? u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); -??? INC (u.n_errors); +??? self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); +??? self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); +??? INC (self.n_errors); ?? END PutErr; ? ?(*-------------------------------------------------------- stack checking ---*) Hm. I think I could have left "self" named "u". I'll try that... ? - Jay ---------------------------------------- > Date: Sat, 8 Jan 2011 09:37:05 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 09:37:05 > > Modified files: > cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > > Log message: > make errors visible on stdout or stderr, much better > now we get: > jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > --- building in I386_DARWIN --- > > new source -> compiling Main.m3 > "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > 4 errors encountered (this should probably say 3) > compilation failed => not building program "pgm" > Fatal Error: package build failed > From jkrell at elego.de Sun Jan 9 01:10:55 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:10:55 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001055.9F43A2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:10:55 Modified files: cm3/m3-db/postgres95/src/: m3makefile Log message: only call configure_system_libs if it is defined; config files out of date? From jkrell at elego.de Sun Jan 9 01:11:32 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:11:32 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109001133.4EC5F2474006@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:11:32 Modified files: cm3/scripts/python/: upgrade.py Log message: CopyConfigForDevelopment => CopyConfigForDistribution From hosking at cs.purdue.edu Sun Jan 9 01:17:30 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:17:30 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110108050121.3B57FCC37A@birch.elegosoft.com> References: <20110108050121.3B57FCC37A@birch.elegosoft.com> Message-ID: That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/08 06:01:20 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > with AtForkPrepare From jay.krell at cornell.edu Sun Jan 9 01:32:11 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 00:32:11 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108050121.3B57FCC37A@birch.elegosoft.com>, Message-ID: Oops, good catch on the leak, and I'll try that now. ?- Jay ---------------------------------------- > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:17:30 -0500 > To: jkrell at elego.de > CC: m3commit at elegosoft.com > Subject: Re: [M3commit] CVS Update: cm3 > > That's not quite the fix I envisioned: I was thinking you should reorder things in AtForkPrepare. > > Note there is now a space leak if RegisterFinalCleanup fails with an exception (it can raise out of memory). > > On Jan 8, 2011, at 6:01 AM, Jay Krell wrote: > > > CVSROOT: /usr/cvs > > Changes by: jkrell at birch. 11/01/08 06:01:20 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > leave initMu before calling RegisterFinalCleanup, to avoid deadlock > > with AtForkPrepare > From jkrell at elego.de Sun Jan 9 01:36:10 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:36:10 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109003611.5C4C2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:36:10 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: go back a versoin, to 1.245 From jkrell at elego.de Sun Jan 9 01:45:31 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 1:45:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109004531.4CCC3CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 01:45:31 Modified files: cm3/scripts/python/: upgrade.py Log message: oops From hosking at cs.purdue.edu Sun Jan 9 01:51:58 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:51:58 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From hosking at cs.purdue.edu Sun Jan 9 01:27:44 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 8 Jan 2011 19:27:44 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110108083705.7F8E22474003@birch.elegosoft.com> Message-ID: <7EC18C1D-B1F2-4948-8369-15591226DCD6@cs.purdue.edu> It always used to be u, not self. On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > Index: src/M3CG_Check.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > retrieving revision 1.13 > diff -u -r1.13 M3CG_Check.m3 > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > @@ -57,6 +57,7 @@ > s_push (t: Type) := Stack_Push; > s_repush () := Stack_Repush; > s_empty () := Stack_Empty; > + PutErr (a, b, c: TEXT) := PutErr; > OVERRIDES > set_error_handler := set_error_handler; > begin_unit := begin_unit; > @@ -185,10 +186,11 @@ > > (*--------------------------------------------------------- low level I/O ---*) > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > BEGIN > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > - INC (u.n_errors); > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > + INC (self.n_errors); > END PutErr; > > (*-------------------------------------------------------- stack checking ---*) > > Hm. I think I could have left "self" named "u". I'll try that... > > - Jay > > > ---------------------------------------- >> Date: Sat, 8 Jan 2011 09:37:05 +0000 >> To: m3commit at elegosoft.com >> From: jkrell at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 11/01/08 09:37:05 >> >> Modified files: >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 >> >> Log message: >> make errors visible on stdout or stderr, much better >> now we get: >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 >> --- building in I386_DARWIN --- >> >> new source -> compiling Main.m3 >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) >> 4 errors encountered (this should probably say 3) >> compilation failed => not building program "pgm" >> Fatal Error: package build failed >> > From jay.krell at cornell.edu Sun Jan 9 02:15:38 2011 From: jay.krell at cornell.edu (Jay K) Date: Sun, 9 Jan 2011 01:15:38 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> References: <20110108083705.7F8E22474003@birch.elegosoft.com> , <4373BF65-287A-4ECE-BE81-1CDC43ADDE83@cs.purdue.edu> Message-ID: Right. I made it "self" to follow the style of "member functions" ("methods", whatever) and then back to "u" for historical stability. Arguably either way. Not a big deal though. ?- Jay ---------------------------------------- > Subject: Re: [M3commit] CVS Update: cm3 > From: hosking at cs.purdue.edu > Date: Sat, 8 Jan 2011 19:51:58 -0500 > CC: jkrell at elego.de; m3commit at elegosoft.com > To: jay.krell at cornell.edu > > It always used to be u, not self. > > On Jan 8, 2011, at 3:38 AM, Jay K wrote: > > > > > Index: src/M3CG_Check.m3 > > =================================================================== > > RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Check.m3,v > > retrieving revision 1.13 > > diff -u -r1.13 M3CG_Check.m3 > > --- src/M3CG_Check.m3 1 Nov 2010 09:37:23 -0000 1.13 > > +++ src/M3CG_Check.m3 8 Jan 2011 08:36:01 -0000 > > @@ -57,6 +57,7 @@ > > s_push (t: Type) := Stack_Push; > > s_repush () := Stack_Repush; > > s_empty () := Stack_Empty; > > + PutErr (a, b, c: TEXT) := PutErr; > > OVERRIDES > > set_error_handler := set_error_handler; > > begin_unit := begin_unit; > > @@ -185,10 +186,11 @@ > > > > (*--------------------------------------------------------- low level I/O ---*) > > > > -PROCEDURE PutErr (u: U; a, b, c: TEXT := NIL) = > > +PROCEDURE PutErr (self: U; a, b, c: TEXT := NIL) = > > BEGIN > > - u.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > - INC (u.n_errors); > > + self.note_error ("********* M3CG_Check ERROR *********** " & a & b & c); > > + self.child.comment ("********* M3CG_Check ERROR *********** ", a, b, c); > > + INC (self.n_errors); > > END PutErr; > > > > (*-------------------------------------------------------- stack checking ---*) > > > > Hm. I think I could have left "self" named "u". I'll try that... > > > > - Jay > > > > > > ---------------------------------------- > >> Date: Sat, 8 Jan 2011 09:37:05 +0000 > >> To: m3commit at elegosoft.com > >> From: jkrell at elego.de > >> Subject: [M3commit] CVS Update: cm3 > >> > >> CVSROOT: /usr/cvs > >> Changes by: jkrell at birch. 11/01/08 09:37:05 > >> > >> Modified files: > >> cm3/m3-sys/m3middle/src/: M3CG_Check.m3 > >> > >> Log message: > >> make errors visible on stdout or stderr, much better > >> now we get: > >> jbook2:p250 jay$ /dev2/cm3/m3-sys/cm3/I386_DARWIN/cm3 > >> --- building in I386_DARWIN --- > >> > >> new source -> compiling Main.m3 > >> "../Main.m3", line 6: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 11: ********* M3CG_Check ERROR *********** bad stack: expected [ Int32 ] got [ Int64 ] > >> "../Main.m3", line 13: ********* M3CG_Check ERROR *********** bad stack: expected [ Int64 ] got [ Int32 ] > >> "../Main.m3", line 1: 3 code generation errors (this line seems unnecessary now!) > >> 4 errors encountered (this should probably say 3) > >> compilation failed => not building program "pgm" > >> Fatal Error: package build failed > >> > > > From jkrell at elego.de Sun Jan 9 03:36:46 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 9 Jan 2011 3:36:46 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109023648.2344ACC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/09 03:36:46 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap later in ForkPrepare, try to fix deadlock with mutex initialization From hosking at elego.de Sun Jan 9 12:01:49 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:01:49 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110149.DD5C52474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:01:49 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: While holding initMu InitMutex invokes RegisterFinalCleanup which acquires heapMu. Make sure that AtForkPrepare and AtForkParent both acquire/release these mutexes in the same order. From hosking at elego.de Sun Jan 9 12:07:13 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 12:07:13 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109110713.A4384CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 12:07:13 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors from conflicts. From hosking at elego.de Sun Jan 9 20:56:31 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 9 Jan 2011 20:56:31 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110109195631.58C2FCC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/09 20:56:31 Modified files: cm3/m3-libs/arithmetic/doc/: backgnd.html Log message: Weird typo: the prefix "stat" was at some point replaced with "statistic", erroneously. From jkrell at elego.de Mon Jan 10 09:03:50 2011 From: jkrell at elego.de (Jay Krell) Date: Mon, 10 Jan 2011 9:03:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110110080350.4F9092474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/10 09:03:50 Modified files: cm3/m3-libs/arithmetic/doc/: wpress.txt Log message: "statistic" => "stat" From hosking at elego.de Tue Jan 11 05:56:50 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 5:56:50 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111045650.61C57247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 05:56:50 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Candidate fix for AtForkPrepare deadlock with InitMutex. From hosking at elego.de Tue Jan 11 06:14:01 2011 From: hosking at elego.de (Antony Hosking) Date: Tue, 11 Jan 2011 6:14:01 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111051402.A39C2247400C@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/11 06:14:01 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: initMu before heapMu to avoid potential deadlock between AtForkPrepare and InitMutex. From jkrell at elego.de Tue Jan 11 09:02:05 2011 From: jkrell at elego.de (Jay Krell) Date: Tue, 11 Jan 2011 9:02:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111080205.9D8F1CC366@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/11 09:02:05 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThreadC.c Log message: whitespace only: right justify line continuation backslashes This is harder to maintain (write/type) but easier to read. From mika at elego.de Tue Jan 11 16:57:22 2011 From: mika at elego.de (Mika Nystrom) Date: Tue, 11 Jan 2011 16:57:22 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110111155722.830B7CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/11 16:57:22 Added files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 m3makefile m3overrides Log message: thread testing program. compile and run, expect to see output as follows: Writing file...done Creating reader threads...done Creating forker threads...done Creating allocator threads...done running... laziest thread is 1294760062 seconds behind laziest thread is 11 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 9 seconds behind laziest thread is 8 seconds behind laziest thread is 10 seconds behind laziest thread is 7 seconds behind laziest thread is 8 seconds behind program stops on its own. From hosking at elego.de Wed Jan 12 01:37:59 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 1:37:59 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112003759.AE706CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 01:37:59 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Oops, so-called "fix" last night was completely broken (tired!). [Mika, please try this latest] From jay.krell at cornell.edu Wed Jan 12 02:58:57 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 01:58:57 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110112003759.AE706CC37A@birch.elegosoft.com> References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense with most of the code implementing it, right? ie: no inCritical, no holder, no condition variables? - Jay ---------------------------------------- > Date: Wed, 12 Jan 2011 01:37:59 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/12 01:37:59 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > Log message: > Oops, so-called "fix" last night was completely broken (tired!). > [Mika, please try this latest] > From jay.krell at cornell.edu Wed Jan 12 03:00:29 2011 From: jay.krell at cornell.edu (Jay K) Date: Wed, 12 Jan 2011 02:00:29 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com>, Message-ID: er, not quite, I forgot there is BroadcastHeap... - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at elego.de; m3commit at elegosoft.com > Date: Wed, 12 Jan 2011 01:58:57 +0000 > Subject: Re: [M3commit] CVS Update: cm3 > > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- > > Date: Wed, 12 Jan 2011 01:37:59 +0000 > > To: m3commit at elegosoft.com > > From: hosking at elego.de > > Subject: [M3commit] CVS Update: cm3 > > > > CVSROOT: /usr/cvs > > Changes by: hosking at birch. 11/01/12 01:37:59 > > > > Modified files: > > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 > > > > Log message: > > Oops, so-called "fix" last night was completely broken (tired!). > > [Mika, please try this latest] > > From jkrell at elego.de Wed Jan 12 08:00:34 2011 From: jkrell at elego.de (Jay Krell) Date: Wed, 12 Jan 2011 8:00:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112070034.7D36CCC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/12 08:00:34 Modified files: cm3/m3-libs/m3core/src/unix/Common/: Uconstants.c Log message: align Jumpbuf_size, which appears needed for Win32 From hosking at cs.purdue.edu Wed Jan 12 18:15:48 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 12:15:48 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110112003759.AE706CC37A@birch.elegosoft.com> Message-ID: <0722C93E-A3B8-493C-A15E-A32ED378F815@cs.purdue.edu> No, not really. Recursive mutexes are not supported on all platforms. Also, in the reql world we will avoid using mutexes in most instances, instead using lock reservation, etc. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On Jan 11, 2011, at 8:58 PM, Jay K wrote: > > We should use PTHREAD_MUTEX_RECURSIVE for the heap lock, and then dispense > with most of the code implementing it, right? > ie: no inCritical, no holder, no condition variables? > > - Jay > > > ---------------------------------------- >> Date: Wed, 12 Jan 2011 01:37:59 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/12 01:37:59 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 >> >> Log message: >> Oops, so-called "fix" last night was completely broken (tired!). >> [Mika, please try this latest] >> From hosking at elego.de Wed Jan 12 19:16:34 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:16:34 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181634.89BC2CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:16:34 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Can we rely on pthread_mutex_t always being a reference? Perhaps not, so don't use the locks array. From hosking at elego.de Wed Jan 12 19:18:08 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:18:08 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112181808.52D04CC37A@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:18:08 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThreadC.c Log message: Eliminate initMu and lock heap instead, to avoid deadlock between InitMutex and AtForkPrepare. From hosking at elego.de Wed Jan 12 19:33:16 2011 From: hosking at elego.de (Antony Hosking) Date: Wed, 12 Jan 2011 19:33:16 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110112183316.3F661CC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/12 19:33:16 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: Fix compile errors. From hosking at elego.de Thu Jan 13 02:37:40 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 2:37:40 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113013740.B85192474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 02:37:40 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for InitMutex instead of initMu to avoid deadlock between Initmutex and AtForkParent. From jay.krell at cornell.edu Thu Jan 13 02:53:06 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 01:53:06 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113013740.B85192474003@birch.elegosoft.com> References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: I haven't lookd, but it sounds like the idea is, use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? ie. resolve problems in a graph by merging nodes. I was also wondering if, maybe, we can initialize mutexex/condition variables eagerly instead of on-demand? Therefore without locking? I know that currently there's no interface from the generated code to the runtime for that. It's a tradeoff. Presumably/hopefully there are many mutexes and condition variables that are never used, and initializing them would just be a slow down. - Jay ---------------------------------------- > Date: Thu, 13 Jan 2011 02:37:40 +0000 > To: m3commit at elegosoft.com > From: hosking at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/13 02:37:40 > > Modified files: > cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 > ThreadPThread.m3 > ThreadPThreadC.c > > Log message: > Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for > InitMutex instead of initMu to avoid deadlock between Initmutex and > AtForkParent. > From hosking at cs.purdue.edu Thu Jan 13 03:59:42 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 12 Jan 2011 21:59:42 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113013740.B85192474003@birch.elegosoft.com> Message-ID: <7F42A0FD-D6EC-49BA-889B-3F15158173DD@cs.purdue.edu> On Jan 12, 2011, at 8:53 PM, Jay K wrote: > > I haven't lookd, but it sounds like the idea is, > use LockHeap/UnlockHeap instead of Lock/Unlock(initMu)? > ie. resolve problems in a graph by merging nodes. Yes. > I was also wondering if, maybe, we can initialize > mutexex/condition variables eagerly instead of on-demand? > Therefore without locking? Seems overkill for types that inherit from MUTEX but are never used for locking. Also, ultimately a Modula-3 MUTEX won't be one-to-one with pthread mutexes. > I know that currently there's no interface from the > generated code to the runtime for that. > > > It's a tradeoff. Presumably/hopefully there are many > mutexes and condition variables that are never used, > and initializing them would just be a slow down. Precisely. > > > - Jay > > ---------------------------------------- >> Date: Thu, 13 Jan 2011 02:37:40 +0000 >> To: m3commit at elegosoft.com >> From: hosking at elego.de >> Subject: [M3commit] CVS Update: cm3 >> >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/13 02:37:40 >> >> Modified files: >> cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 >> ThreadPThread.m3 >> ThreadPThreadC.c >> >> Log message: >> Revert to old LockHeap/UnlockHeap inplementation, but retain LockHeap for >> InitMutex instead of initMu to avoid deadlock between Initmutex and >> AtForkParent. >> From hosking at elego.de Thu Jan 13 06:58:48 2011 From: hosking at elego.de (Antony Hosking) Date: Thu, 13 Jan 2011 6:58:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113055848.D4DF02474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/13 06:58:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: LockHeap/UnlockHeap in case we already did this in RTCollector AtForkPrepare/AtForkParent. From jkrell at elego.de Thu Jan 13 15:58:29 2011 From: jkrell at elego.de (Jay Krell) Date: Thu, 13 Jan 2011 15:58:29 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113145829.72EAD2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/13 15:58:29 Modified files: cm3/m3-sys/m3front/src/misc/: Marker.m3 cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: __builtin_alloca didn't work w/o translation among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca and do the comparison by pointer equality (since gcc uses string interning) I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near anything else. From jay.krell at cornell.edu Thu Jan 13 16:00:24 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:00:24 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110113145829.72EAD2474003@birch.elegosoft.com> References: <20110113145829.72EAD2474003@birch.elegosoft.com> Message-ID: Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 13 16:06:37 2011 From: jay.krell at cornell.edu (Jay K) Date: Thu, 13 Jan 2011 15:06:37 +0000 Subject: [M3commit] CVS Update: cm3 In-Reply-To: References: <20110113145829.72EAD2474003@birch.elegosoft.com>, Message-ID: Hm. I'll try the hashtable instead. - Jay From: jay.krell at cornell.edu To: jkrell at elego.de; m3commit at elegosoft.com Subject: RE: [M3commit] CVS Update: cm3 Date: Thu, 13 Jan 2011 15:00:24 +0000 Index: m3-sys/m3front/src/misc/Marker.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v retrieving revision 1.8 diff -u -r1.8 Marker.m3 --- m3-sys/m3front/src/misc/Marker.m3 6 Jan 2011 20:40:16 -0000 1.8 +++ m3-sys/m3front/src/misc/Marker.m3 13 Jan 2011 14:56:53 -0000 @@ -248,7 +248,7 @@ END; (* void* _alloca(size_t); *) IF (alloca = NIL) THEN - alloca := CG.Import_procedure (M3ID.Add ("_alloca"), 1, CG.Type.Addr, + alloca := CG.Import_procedure (M3ID.Add ("m3_alloca"), 1, CG.Type.Addr, Target.DefaultCall, new); IF (new) THEN EVAL CG.Declare_param (M3ID.NoID, Target.Word.size, Target.Word.align, Index: m3-sys/m3cc/gcc/gcc/m3cg/parse.c =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3cc/gcc/gcc/m3cg/parse.c,v retrieving revision 1.477 diff -u -r1.477 parse.c --- m3-sys/m3cc/gcc/gcc/m3cg/parse.c 5 Jan 2011 14:34:53 -0000 1.477 +++ m3-sys/m3cc/gcc/gcc/m3cg/parse.c 13 Jan 2011 14:56:53 -0000 @@ -473,6 +473,8 @@ #define t_void void_type_node static GTY (()) tree t_set; +static tree m3_alloca; + static const struct { UINT32 type_id; tree* t; } builtin_uids[] = { { UID_INTEGER, &t_int }, { UID_LONGINT, &t_longint }, @@ -1750,6 +1752,7 @@ bits_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER); bytes_per_integer_tree = build_int_cst (t_word, BITS_PER_INTEGER / BITS_PER_UNIT); tree stdcall = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("stdcall")); + m3_alloca = get_identifier_with_length (CONSTANT_STRING_AND_LENGTH ("m3_alloca")); stdcall_list = build_tree_list (stdcall, NULL); t_set = m3_build_pointer_type (t_word); @@ -2979,22 +2982,9 @@ tree *slot = (tree *)htab_find_slot (builtins, p, NO_INSERT); if (slot) - { p = *slot; - } - else - { - const char *name = IDENTIFIER_POINTER (DECL_NAME (p)); - if (name[0] == 'a' || name[0] == '_') - { - if (strcmp(name, "alloca") == 0 - || strcmp(name, "_alloca") == 0 - || strcmp(name, "__builtin_alloca") == 0) - { - p = built_in_decls[BUILT_IN_ALLOCA]; - } - } - } + else if (DECL_NAME (p) == m3_alloca) + p = built_in_decls[BUILT_IN_ALLOCA]; return p; } - Jay > Date: Thu, 13 Jan 2011 15:58:29 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 11/01/13 15:58:29 > > Modified files: > cm3/m3-sys/m3front/src/misc/: Marker.m3 > cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c > > Log message: > __builtin_alloca didn't work w/o translation > among alloca, _alloca, __builtin_alloca, make up our own name, m3_alloca > and do the comparison by pointer equality (since gcc uses > string interning) > I'd also go for _m3_alloca, __m3_alloca, or alloca, or darn near > anything else. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at elego.de Thu Jan 13 19:16:48 2011 From: mika at elego.de (Mika Nystrom) Date: Thu, 13 Jan 2011 19:16:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110113181648.6D80ECC37B@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/13 19:16:48 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: updated documentation/in-line comments for thread testing program to describe design and usage of program From jkrell at elego.de Fri Jan 14 08:19:39 2011 From: jkrell at elego.de (Jay Krell) Date: Fri, 14 Jan 2011 8:19:39 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114071939.5EEB8CC10F@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/14 08:19:39 Modified files: cm3/m3-sys/m3cc/gcc/gcc/m3cg/: parse.c Log message: There is no need to put all/any of the builtins into a hashtable. All of the uses are very direct/special, except for m3_alloca. That is, the frontend doesn't generate regular function calls to any of them, except m3_alloca. From mika at elego.de Fri Jan 14 14:52:05 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 14:52:05 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114135206.1F33F2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 14:52:05 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Make diagnostic output snazzier. Now prints median and minimum ages as well as maximum age, for each category of threads. From mika at elego.de Fri Jan 14 15:05:37 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:05:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140537.688332474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:05:37 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Even snazzier: ignore exceptions that happen during setup, print diagnostics for exceptions that happen during running, and eliminate all compiler warnings. From mika at elego.de Fri Jan 14 15:09:02 2011 From: mika at elego.de (Mika Nystrom) Date: Fri, 14 Jan 2011 15:09:02 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110114140902.199AD2474008@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/14 15:09:02 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Fix comments to match code. From mika at elego.de Sat Jan 15 14:39:09 2011 From: mika at elego.de (Mika Nystrom) Date: Sat, 15 Jan 2011 14:39:09 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110115133909.E6F07CC125@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/15 14:39:09 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: Add a fourth class of threads to thread tester: thread-creator threads. From mika at elego.de Sun Jan 16 02:18:27 2011 From: mika at elego.de (Mika Nystrom) Date: Sun, 16 Jan 2011 2:18:27 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116011827.DD31F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/16 02:18:27 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: give the user something to look at while the program runs (also shows off deadlock well) From dabenavidesd at yahoo.es Sun Jan 16 03:27:40 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 02:27:40 +0000 (GMT) Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116011827.DD31F2474003@birch.elegosoft.com> Message-ID: <19786.44534.qm@web29702.mail.ird.yahoo.com> Hi all: Yes, sure just that we need also for range checks and type checks, I mean, I guess the problem are not the client programs by itself if so why do you think they crashed unsafely? The problem is to test the implementation more deeply, perhaps Tony is the best man to do that part of the job I think. However unsafe code there is guaranteed by others to be right, I tend to feel that in those cases a more detailed test compliance is needed, I mean, we don't guarantee every platform behaves exactly as we think of it. Perhaps Jay could be indicated for that part of the job, I think. Thanks in advance --- El s?b, 15/1/11, Mika Nystrom escribi?: > De: Mika Nystrom > Asunto: [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:18 > CVSROOT: /usr/cvs > Changes by: mika at birch. > 11/01/16 02:18:27 > > Modified files: > cm3/m3-libs/m3core/tests/thread/src/: > Main.m3 > > Log message: > give the user something to look at while > the program runs (also shows off deadlock well) > > From dabenavidesd at yahoo.es Sun Jan 16 04:36:23 2011 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 16 Jan 2011 03:36:23 +0000 (GMT) Subject: [M3commit] [M3devel] CVS Update: cm3 In-Reply-To: <19786.44534.qm@web29702.mail.ird.yahoo.com> Message-ID: <878606.72309.qm@web29713.mail.ird.yahoo.com> Hi all: The best source of a check for both cases is a test set for Modula-3 vs C threading programs. I mean what source of it might come to crash if we allow just normal range and type checking by itself on the Modula-3 programs, just C part that we don't have, I assume the Modula-3 parts touching it are thread safe as it's the collector, if a program is to crash badly, it should crash in the Modula-3 version and be unsafely crashed at a certain level on C in some cases (sort of the exceptional cases), I'm more interested that it doesn't crash on both sides, sort of being a good M3 behaved guy, that is, what it would mean is we do have a problem on the threading library implementation (not tested, unmarked exception, or uncaught ones?), given platforms behave well, that sometimes I think they do, but we don't know, that's why we need test some assertions if so (not generate the code if you want to run assembly smoothly sure). Perhaps the best approach here is just to test it right goes into C mode and then is just part of the safe modules to guard type check the bad inputs or outputs ISTYPE() is a good way of doing it if you may allow me say. Thanks in advance. --- El s?b, 15/1/11, Daniel Alejandro Benavides D. escribi?: > De: Daniel Alejandro Benavides D. > Asunto: Re: [M3devel] [M3commit] CVS Update: cm3 > Para: m3commit at elegosoft.com, mika at elego.de, m3devel at elegosoft.com > Fecha: s?bado, 15 de enero, 2011 21:27 > Hi all: > Yes, sure just that we need also for range checks and type > checks, I mean, I guess the problem are not the client > programs by itself if so why do you think they crashed > unsafely? > The problem is to test the implementation more deeply, > perhaps Tony is the best man to do that part of the job I > think. > However unsafe code there is guaranteed by others to be > right, I tend to feel that in those cases a more detailed > test compliance is needed, I mean, we don't guarantee every > platform behaves exactly as we think of it. Perhaps Jay > could be indicated for that part of the job, I think. > Thanks in advance > > --- El s?b, 15/1/11, Mika Nystrom > escribi?: > > > De: Mika Nystrom > > Asunto: [M3commit] CVS Update: cm3 > > Para: m3commit at elegosoft.com > > Fecha: s?bado, 15 de enero, 2011 21:18 > > CVSROOT: /usr/cvs > > Changes by: > mika at birch. > > 11/01/16 02:18:27 > > > > Modified files: > > > cm3/m3-libs/m3core/tests/thread/src/: > > Main.m3 > > > > Log message: > > give the user something to > look at while > > the program runs (also shows off deadlock well) > > > > > > > > From hosking at elego.de Sun Jan 16 20:58:37 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 20:58:37 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116195837.5997B2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 20:58:37 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: No need to LockHeap/UnlockHeap at fork. Simply reset flags recording threads started. From hosking at elego.de Sun Jan 16 21:02:17 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:02:17 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200217.B82172474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:02:17 Modified files: cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 Log message: Eliminate AtForkPrepare and AtForkParent. From hosking at elego.de Sun Jan 16 21:06:48 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 21:06:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116200648.58E012474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 21:06:48 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.i3 ThreadPThread.m3 ThreadPThreadC.c Log message: Reinstate initMu. LockHeap should never be called before locking any of activeMu, slotsMu, initMu, perfMu. From hosking at elego.de Sun Jan 16 22:25:21 2011 From: hosking at elego.de (Antony Hosking) Date: Sun, 16 Jan 2011 22:25:21 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110116212521.EEE5F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: hosking at birch. 11/01/16 22:25:21 Modified files: cm3/m3-libs/m3core/src/thread/PTHREAD/: ThreadPThread.m3 Log message: One more deadlock between activeMu and LockHeap. SuspendOthers can be called while LockHeap, which then locks activeMu. From mika at elego.de Mon Jan 17 05:58:56 2011 From: mika at elego.de (Mika Nystrom) Date: Mon, 17 Jan 2011 5:58:56 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110117045856.65FE62474007@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: mika at birch. 11/01/17 05:58:56 Modified files: cm3/m3-libs/m3core/tests/thread/src/: Main.m3 Log message: add a fifth type of thread---"locker" thread. From jay.krell at cornell.edu Mon Jan 17 06:42:12 2011 From: jay.krell at cornell.edu (jay.krell at cornell.edu) Date: Sun, 16 Jan 2011 21:42:12 -0800 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <20110116195837.5997B2474003@birch.elegosoft.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> Message-ID: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). - Jay On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > CVSROOT: /usr/cvs > Changes by: hosking at birch. 11/01/16 20:58:37 > > Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 > > Log message: > No need to LockHeap/UnlockHeap at fork. > Simply reset flags recording threads started. > From hosking at cs.purdue.edu Mon Jan 17 13:55:57 2011 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 17 Jan 2011 07:55:57 -0500 Subject: [M3commit] CVS Update: cm3 In-Reply-To: <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> References: <20110116195837.5997B2474003@birch.elegosoft.com> <58925E10-9809-470F-8260-4C63B16286BB@gmail.com> Message-ID: <08342311-619A-443A-9685-97E5BD6E9404@cs.purdue.edu> It gets locked in ThreadPThread atfork. Sent from my iPhone On Jan 17, 2011, at 12:42 AM, jay.krell at cornell.edu wrote: > I haven't read the diff yet, but please not that one thread may have the heap locked while another calls fork(). There is no coordination between fork() calls and the heap, other than pthread_atfork(). > > - Jay > > On Jan 16, 2011, at 8:58 PM, hosking at elego.de (Antony Hosking) wrote: > >> CVSROOT: /usr/cvs >> Changes by: hosking at birch. 11/01/16 20:58:37 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTCollector.m3 >> >> Log message: >> No need to LockHeap/UnlockHeap at fork. >> Simply reset flags recording threads started. >> From rodney at elego.de Tue Jan 18 03:21:42 2011 From: rodney at elego.de (Rodney M. Bates) Date: Tue, 18 Jan 2011 3:21:42 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110118022143.132DC2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: rodney at birch. 11/01/18 03:21:42 Modified files: cm3/m3-sys/m3gdb/gdb/gdb/: Tag: release_branch_cm3_5_8 i386-tdep.c Log message: An incomplete fix to get results of floating type working on m3gdb-typed calls to functions. This needs extensive rework. m3gdb borrows heavily from gdb for handling floating values. But gdb has only one floating type code (TYPE_CODE_FLT) and it distinguishes the different floating types by size. This is not really sufficient for M3, because there are 3 floating types, not necessarily all the same size. New type codes for M3 have been in here for years, but many places in existing gdb code need to recognize them. Also, existing gdb printing and other handling of floating values may not be exacly right for m3gdb anyway. It might be nice to just call M3 code in, e.g., Fmt. From jkrell at elego.de Sat Jan 22 20:39:19 2011 From: jkrell at elego.de (Jay Krell) Date: Sat, 22 Jan 2011 20:39:19 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110122193919.A61892474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/22 20:39:19 Modified files: cm3/m3-sys/m3cc/gcc-4.5/include/: libiberty.h Log message: #include libgen.h instead of declaring basename From jkrell at elego.de Sun Jan 30 11:41:48 2011 From: jkrell at elego.de (Jay Krell) Date: Sun, 30 Jan 2011 11:41:48 () Subject: [M3commit] CVS Update: cm3 Message-ID: <20110130104149.4129F2474003@birch.elegosoft.com> CVSROOT: /usr/cvs Changes by: jkrell at birch. 11/01/30 11:41:48 Modified files: cm3/m3-sys/m3front/src/misc/: CG.i3 Log message: remove one newline