[armedbear-devel] Stack overflow when compiler macro with fallback is triggered
(eval-when (:compile-toplevel :load-toplevel :execute) (defun foo () 99) (define-compiler-macro foo () `(locally (declare (notinline foo)) (foo)))) (defun call-foo () (foo)) Of course, the use case is a compiler macro that says, "OK, let's optimize! ... Never mind, I don't want to optimize that." Armed Bear Common Lisp 1.0.1-svn-13750-13751 Java 1.7.0_04 Oracle Corporation [...] ; (DEFUN FOO ...) ; (DEFINE-COMPILER-MACRO FOO ...) ; (DEFUN CALL-FOO ...) java.lang.StackOverflowError at org.armedbear.lisp.StructureObject$pf_make_structure.execute(StructureObject.java:671) at org.armedbear.lisp.Symbol.execute(Symbol.java:865) at org.armedbear.lisp.LispThread.execute(LispThread.java:760) at org.armedbear.lisp.jvm_714.execute(jvm.lisp:567) at org.armedbear.lisp.CompiledClosure.execute(CompiledClosure.java:92) at org.armedbear.lisp.Symbol.execute(Symbol.java:775) at org.armedbear.lisp.LispThread.execute(LispThread.java:633) at org.armedbear.lisp.jvm_746.execute(jvm.lisp:572) at org.armedbear.lisp.Symbol.execute(Symbol.java:775) at org.armedbear.lisp.LispThread.execute(LispThread.java:633) at org.armedbear.lisp.compiler_pass1_26.execute(compiler-pass1.lisp:487) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_61.execute(compiler-pass1.lisp:1204) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_61.execute(compiler-pass1.lisp:1204) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.compiler_pass1_20.execute(compiler-pass1.lisp:383) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_26.execute(compiler-pass1.lisp:487) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_61.execute(compiler-pass1.lisp:1204) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_61.execute(compiler-pass1.lisp:1204) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.compiler_pass1_20.execute(compiler-pass1.lisp:383) at org.armedbear.lisp.Symbol.execute(Symbol.java:785) at org.armedbear.lisp.LispThread.execute(LispThread.java:649) at org.armedbear.lisp.compiler_pass1_26.execute(compiler-pass1.lisp:487) [...]
On Jun 3, 2012, at 22:19 , James M. Lawrence wrote:
(eval-when (:compile-toplevel :load-toplevel :execute) (defun foo () 99)
(define-compiler-macro foo () `(locally (declare (notinline foo)) (foo))))
(defun call-foo () (foo))
Of course, the use case is a compiler macro that says, "OK, let's optimize! ... Never mind, I don't want to optimize that."
Filed [as ticket #214][1]; thanks for the report! [1]: http://trac.common-lisp.net/armedbear/ticket/214 By the way, [lparallel][2] is looking real sweet! I'm looking forward to find some time to use it to optimize ABCL's usage of Bordeaux-Threads. [2]: https://github.com/lmj/lparallel
On Tue, Jun 5, 2012 at 2:30 PM, Mark Evenson <evenson@panix.com> wrote:
On Jun 3, 2012, at 22:19 , James M. Lawrence wrote:
(eval-when (:compile-toplevel :load-toplevel :execute) (defun foo () 99)
(define-compiler-macro foo () `(locally (declare (notinline foo)) (foo))))
(defun call-foo () (foo))
Of course, the use case is a compiler macro that says, "OK, let's optimize! ... Never mind, I don't want to optimize that."
Filed [as ticket #214][1]; thanks for the report!
Shouldn't &whole be used for that? The CLHS says [1] (emphasis mine): "Unlike an ordinary macro, a compiler macro can decline to provide an expansion merely by returning a form that is __the same as the original__ (which can be obtained by using &whole)."
By the way, [lparallel][2] is looking real sweet! I'm looking forward to find some time to use it to optimize ABCL's usage of Bordeaux-Threads.
Agreed on lparallel :) [1] http://clhs.lisp.se/Body/m_define.htm -- Some gratuitous spam: http://ripple-project.org Ripple, social credit system http://villages.cc Villages.cc, Ripple-powered community economy http://common-lisp.net/project/armedbear ABCL, Common Lisp on the JVM http://code.google.com/p/tapulli my current open source projects http://www.manydesigns.com/ ManyDesigns Portofino, open source model-driven Java web application framework
Shouldn't &whole be used for that? The CLHS says [1] (emphasis mine): "Unlike an ordinary macro, a compiler macro can decline to provide an expansion merely by returning a form that is __the same as the original__ (which can be obtained by using &whole)."
Yes, that's the right way to inhibit compiler-macro expansion, but local notinline declaration should be able to inhibit it too. I guess ABCL's compiler ignores this declaration, which isn't good.
[I just noticed this wasn't sent to the list.] On Tue, Jun 5, 2012 at 8:41 AM, Alessio Stalla <alessiostalla@gmail.com> wrote:
On Tue, Jun 5, 2012 at 2:30 PM, Mark Evenson <evenson@panix.com> wrote:
On Jun 3, 2012, at 22:19 , James M. Lawrence wrote:
(eval-when (:compile-toplevel :load-toplevel :execute) (defun foo () 99)
(define-compiler-macro foo () `(locally (declare (notinline foo)) (foo))))
(defun call-foo () (foo))
Of course, the use case is a compiler macro that says, "OK, let's optimize! ... Never mind, I don't want to optimize that."
Filed [as ticket #214][1]; thanks for the report!
Shouldn't &whole be used for that?
Yes I do use a &whole parameter, which handles the case of the fallback being determined at compile time. Once I have evaluated a parameter, however, the fallback goes to a notinline call inside the expansion. My example is pmap-into, which has the vector-into-vector case open-coded. It would be neat if a macro could query declared or inferred types, but failing that we must evaluate and check. Thanks to all for the endorsement :)
Hi James, Just committed the fix for the test case which I had in ticket #214 - taken from your report below. So, it's fixed in trunk! Hopefully we can come up with a good protocol for the "interrupted" threads to be able to terminate threads in a nice unwind-protected manner. Anyway, we're a small step closer to correctly (completely) running lparallel! Bye, Erik. On Fri, Jun 15, 2012 at 3:31 PM, James M. Lawrence <llmjjmll@gmail.com>wrote:
[I just noticed this wasn't sent to the list.]
On Tue, Jun 5, 2012 at 8:41 AM, Alessio Stalla <alessiostalla@gmail.com> wrote:
On Tue, Jun 5, 2012 at 2:30 PM, Mark Evenson <evenson@panix.com> wrote:
On Jun 3, 2012, at 22:19 , James M. Lawrence wrote:
(eval-when (:compile-toplevel :load-toplevel :execute) (defun foo () 99)
(define-compiler-macro foo () `(locally (declare (notinline foo)) (foo))))
(defun call-foo () (foo))
Of course, the use case is a compiler macro that says, "OK, let's optimize! ... Never mind, I don't want to optimize that."
Filed [as ticket #214][1]; thanks for the report!
Shouldn't &whole be used for that?
Yes I do use a &whole parameter, which handles the case of the fallback being determined at compile time. Once I have evaluated a parameter, however, the fallback goes to a notinline call inside the expansion.
My example is pmap-into, which has the vector-into-vector case open-coded. It would be neat if a macro could query declared or inferred types, but failing that we must evaluate and check.
Thanks to all for the endorsement :)
_______________________________________________ armedbear-devel mailing list armedbear-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
participants (5)
-
Alessio Stalla
-
Alex Mizrahi
-
Erik Huelsmann
-
James M. Lawrence
-
Mark Evenson