From xemacs-m  Mon May  5 16:30:59 1997
Received: from mailbox2.ucsd.edu (mailbox2.ucsd.edu [132.239.1.54])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id QAA11954
	for <xemacs-beta@xemacs.org>; Mon, 5 May 1997 16:30:55 -0500 (CDT)
Received: from sdnp5.ucsd.edu (sdnp5.ucsd.edu [132.239.79.10]) by mailbox2.ucsd.edu (8.8.5/8.6.9) with SMTP id OAA05775 for <xemacs-beta@xemacs.org>; Mon, 5 May 1997 14:30:55 -0700 (PDT)
Received: by sdnp5.ucsd.edu (SMI-8.6/SMI-SVR4)
	id OAA01980; Mon, 5 May 1997 14:31:57 -0700
To: xemacs-beta@xemacs.org
Subject: Re: `mapcar' calling SUBRs directly
References: <kigenbomwik.fsf@jagor.srce.hr> 	<QQcnyy27061.199705031911@crystal.WonderWorks.COM> 	<kig207omjh5.fsf@jagor.srce.hr> 	<QQcnzb28042.199705031954@crystal.WonderWorks.COM> 	<kigyb9wl3ip.fsf@jagor.srce.hr> <QQcody26201.199705050337@crystal.WonderWorks.COM> <kig3es2imz6.fsf@jagor.srce.hr>
X-Face: "oX;zS#-JU$-,WKSzG.1gGE]x^cIg!hW.dq>.f6pzS^A+(k!T|M:}5{_%>Io<>L&{hO7W4cicOQ|>/lZ1G(m%7iaCf,6Qgk0%%Bz7b2-W3jd0m_UG\Y;?]}4s0O-U)uox>P3JN)9cm]O\@,vy2e{`3pb!"pqmRy3peB90*2L
Mail-Copies-To: never
Mime-Version: 1.0 (generated by tm-edit 7.106)
Content-Type: multipart/mixed;
 boundary="Multipart_Mon_May__5_14:31:53_1997-1"
Content-Transfer-Encoding: 7bit
From: David Moore <dmoore@ucsd.edu>
Date: 05 May 1997 14:31:54 -0700
In-Reply-To: Hrvoje Niksic's message of 05 May 1997 06:03:57 +0200
Message-ID: <rvwwpd61x1.fsf@sdnp5.ucsd.edu>
Lines: 185
X-Mailer: Gnus v5.4.45/XEmacs 20.1

--Multipart_Mon_May__5_14:31:53_1997-1
Content-Type: text/plain; charset=US-ASCII

Hrvoje Niksic <hniksic@srce.hr> writes:

> DAVID: The jury, consisting of an equal number of gprof and Quantify
> runs has reached the conclusion that...
> 
> A SPECTATOR WITH STRONG FINNISH ACCENT: But have you used elp?

Ok, this quarter is quite a heavy load (writing a nice optimizing
compiler in common lisp -- god's choice of a language for optimizing
compilers) and a software engineering class with 20 hours a week outside 
of class....

But this message did remind me that I do have a rewritten ELP (w/o
comments - ha ha ha) which tracks call-graph information and handles
recursive functions.

I wrote it in december and planned to clean it up.  In january I sent it 
to Barry, in case he had time to work on anything other than cc-mode.
Last month I sent it to Per for custom.  As you can see I never really
found the time to clean it up, and I guess no one else did either.  If
anyone is really hot for it, let me know, I've been reluctant to give it 
out as-is, because it is making some subtle choices, and I've been
hoping to supercede by adding call-graph support to the XEmacs builtin
C profiling. 


btw, I think your patch to allow direct subr calls from mapcar1 was gc
safe, but it will lose profiling and backtrace information (which you
don't want to lose).  Also, it's probably a pretty rare case to have the
function be a subr.  It'll speed up the occasional (mapcar 'list xxx)
and 'car/'cdr a bit, but most uses of mapcar and nearly all of mapc
(except with 'prin1 and 'eval -- which are rare or slow respectively)
involve a non-subr func.


There is a good way where you can profile very specifically what kinds
of functions are given to mapcar1.  Then based on your profiling you may 
decide that making mapcar1 more complicated, needing to be kept synched
with other backtrace changes, and larger (affecting code cache) is worth 
the change.  My gut reaction is that it won't be worth it.


This patch (not to be applied to the distribtion) provides two variables
counting the number times mapcar1 could have used the subr, and the
number of times it couldn't.  They are c variables, if you want to read
them, I suggest either starting your xemacs in gdb or attaching at some
later point.  Break into the debugger and print their values.  Note this
version will start with counts including information from the dump.
Normally I clear these kind of counter variables in the files init_X
function, if it has one.  Either clear it with gdb, or just subtract off 
the initial value.

I suggest running a day or so in your normal editting/gnus manner.
Don't run any micro-benchmarks yourself, such as trying (mapcar 'car x)
a lot, etc.

The variables are named oj_mapcar1_subr and oj_mapcar1_nosubr.

Here's a sample gdb run showing the before starting, and after it loaded 
my .emacs:


: sdnp5 ; gdb ./xemacs
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (sparc-sun-solaris2.5), 
Copyright 1996 Free Software Foundation, Inc...
>>> Use the `temacs' command to run temacs


(gdb) print oj_mapcar1_subr
$1 = 245
(gdb) print oj_mapcar1_nosubr
$2 = 73
(gdb) run -display fondi:0
Starting program: /export/tmp/xemacs-20.1/src/./xemacs -display fondi:0
^C
Program received signal SIGINT, Interrupt.
0x6faf68ac in _poll ()
(gdb) print oj_mapcar1_subr
$3 = 341
(gdb) print oj_mapcar1_nosubr
$4 = 400
(gdb) cont



--Multipart_Mon_May__5_14:31:53_1997-1
Content-Type: application/octet-stream; type=patch
Content-Disposition: attachment; filename="fns.c.diff"
Content-Transfer-Encoding: 7bit

--- fns.c.orig	Wed Apr  9 22:56:42 1997
+++ fns.c	Mon May  5 14:27:28 1997
@@ -3157,6 +3157,9 @@
 
  If VALS is a null pointer, do not accumulate the results. */
 
+int oj_mapcar1_subr;
+int oj_mapcar1_nosubr;
+
 static void
 mapcar1 (int leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
 {
@@ -3165,9 +3168,30 @@
   int i;
   struct gcpro gcpro1, gcpro2, gcpro3;
   Lisp_Object result;
+  int was_subr = 0;
 
   GCPRO3 (dummy, fn, seq);
 
+  /* Recognize whether FN is a subr, or a symbol whose symbol-function
+     is a subr.  If yes, and the subr takes exactly one argument, make
+     subr point to the C code of the subr itself.  */
+  if (SUBRP (fn))
+    {
+      if (XSUBR (fn)->min_args == 1 && XSUBR (fn)->max_args == 1)
+	was_subr = 1;
+    }
+  else if (SYMBOLP (fn))
+    {
+      Lisp_Object func = XSYMBOL (fn)->function;
+
+      if (SUBRP (func) && XSUBR (func)->min_args == 1
+	  && XSUBR (func)->max_args == 1)
+	{
+	  was_subr = 1;
+	}
+    }
+
+
   if (vals)
     {
       /* Don't let vals contain any garbage when GC happens.  */
@@ -3185,6 +3209,10 @@
     {
       for (i = 0; i < leni; i++)
 	{
+	  if (was_subr)
+	    oj_mapcar1_subr++;
+	  else
+	    oj_mapcar1_nosubr++;
 	  dummy = vector_data (XVECTOR (seq))[i];
 	  result = call1 (fn, dummy);
 	  if (vals)
@@ -3196,6 +3224,10 @@
       struct Lisp_Bit_Vector *v = XBIT_VECTOR (seq);
       for (i = 0; i < leni; i++)
 	{
+	  if (was_subr)
+	    oj_mapcar1_subr++;
+	  else
+	    oj_mapcar1_nosubr++;
 	  XSETINT (dummy, bit_vector_bit (v, i));
 	  result = call1 (fn, dummy);
 	  if (vals)
@@ -3206,6 +3238,10 @@
     {
       for (i = 0; i < leni; i++)
 	{
+	  if (was_subr)
+	    oj_mapcar1_subr++;
+	  else
+	    oj_mapcar1_nosubr++;
 	  result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
 	  if (vals)
 	    vals[i] = result;
@@ -3216,6 +3252,10 @@
       tail = seq;
       for (i = 0; i < leni; i++)
 	{
+	  if (was_subr)
+	    oj_mapcar1_subr++;
+	  else
+	    oj_mapcar1_nosubr++;
 	  result = call1 (fn, Fcar (tail));
 	  if (vals)
 	    vals[i] = result;

--Multipart_Mon_May__5_14:31:53_1997-1--

