changeset 5554:a42e686a01bf

Automated merge with file:///Sources/xemacs-21.5-checked-out
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 24 Aug 2011 11:07:26 +0100
parents 85210c453a97 (diff) 62edcc6a11ec (current diff)
children a39cd9dc92ba
files
diffstat 6 files changed, 187 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/man/ChangeLog	Wed Aug 24 11:06:41 2011 +0100
+++ b/man/ChangeLog	Wed Aug 24 11:07:26 2011 +0100
@@ -1,3 +1,9 @@
+2011-08-14  Mike Sperber  <mike@xemacs.org>
+
+	* xemacs-faq.texi:
+	* xemacs/packages.texi: Reflect change of location of packages
+	from lib/ to share/.
+
 2011-08-09  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* cl.texi (Argument Lists):
--- a/man/xemacs-faq.texi	Wed Aug 24 11:06:41 2011 +0100
+++ b/man/xemacs-faq.texi	Wed Aug 24 11:07:26 2011 +0100
@@ -168,7 +168,7 @@
 If you do not have makeinfo installed, you may @uref{xemacs-faq.info,
 download the faq} in info format, and install it in @file{<XEmacs
 library directory>/info/}. For example in
-@file{/usr/local/lib/xemacs-21.4/info/}.
+@file{/usr/local/lib/xemacs-21.5/info/}.
 
 @end itemize
 
@@ -3285,14 +3285,14 @@
 
 Install them on Unix and Mac OS X using the shell/Terminal command
 
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xf -}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xf -}
 
 Where @samp{$prefix} is what you gave to the @samp{--prefix} flag to
 @file{configure}, and defaults to @file{/usr/local}.
 
 If you have GNU tar you can use:
 
-@code{cd $prefix/lib/xemacs ; tar zxvf <tarballname>}
+@code{cd $prefix/share/xemacs ; tar zxvf <tarballname>}
 
 If you have the packages somewhere nonstandard and don't want to bother
 with @samp{$prefix} (for example, you're a developer and are compiling
@@ -3347,8 +3347,8 @@
 package (version 1.48):
 
 @example
-   mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
-   cd $prefix/lib/xemacs/xemacs-packages RET
+   mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+   cd $prefix/share/xemacs/xemacs-packages RET
    gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
 @end example
 
@@ -3362,8 +3362,8 @@
 hierarchy, i.e. for the @samp{mule-base} package, version 1.37:
 
 @example
-   mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
-   cd $prefix/lib/xemacs/mule-packages RET
+   mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+   cd $prefix/share/xemacs/mule-packages RET
    gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
 @end example
 
@@ -3509,18 +3509,18 @@
 Normally, there are three system wide hierarchies, like this:
 
 @example
-$prefix/lib/xemacs/xemacs-packages/
+$prefix/sahre/xemacs/xemacs-packages/
      Normal packages go here.
 
-$prefix/lib/xemacs/mule-packages/
+$prefix/share/xemacs/mule-packages/
      Mule packages go here and are only searched by MULE-enabled XEmacsen.
 
-$prefix/lib/xemacs/site-packages/
+$prefix/share/xemacs/site-packages/
      Local and 3rd party packages go here.
 @end example
 
 This is what you get when you untar the SUMO tarballs under
-@file{$prefix/lib/xemacs}.
+@file{$prefix/share/xemacs}.
 
 @file{$prefix} is specified using the @samp{--prefix} parameter to
 @file{configure}, and defaults to @file{usr/local}.
@@ -3533,7 +3533,7 @@
 @file{lib/xemacs}.  The XEmacs executable (under Unix at least) is
 installed by default in @file{/usr/local/bin}; this explains why
 XEmacs in its default installation will find packages that you put
-under @file{/usr/local/lib/xemacs}.
+under @file{/usr/local/share/xemacs}.
 
 You can specify where exactly XEmacs looks for packages by using the
 @samp{--with-user-packages} (an alias for @samp{--with-early-packages})
@@ -3557,7 +3557,7 @@
 The site-packages hierarchy replaces the old @file{site-lisp}
 directory.  XEmacs no longer looks into a @file{site-lisp} directly by
 default.  A good place to put @file{site-start.el} would be in
-@file{$prefix/lib/xemacs/site-packages/lisp/}.
+@file{$prefix/share/xemacs/site-packages/lisp/}.
 
 @node Q2.1.7, Q2.2.1, Q2.1.6, Installation
 @unnumberedsubsec Q2.1.7: EFS fails with "500 AUTH not understood" (NEW)
@@ -6576,7 +6576,7 @@
 The package @code{ps-print}, which is now included with XEmacs, provides
 the ability to do this.  The source code contains complete instructions
 on its use, in
-@file{$prefix/lib/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
+@file{$prefix/share/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
 being the default location of an installed ps-print package.
 
 @node Q5.2.3, Q5.2.4, Q5.2.2, External Subsystems
--- a/man/xemacs/packages.texi	Wed Aug 24 11:06:41 2011 +0100
+++ b/man/xemacs/packages.texi	Wed Aug 24 11:07:26 2011 +0100
@@ -311,8 +311,8 @@
 package (version 1.48):
 
 @example
-   mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
-   cd $prefix/lib/xemacs/xemacs-packages RET
+   mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+   cd $prefix/share/xemacs/xemacs-packages RET
    gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
 
 Or if you have GNU tar, the last step can be:
@@ -324,8 +324,8 @@
 hierarchy, i.e. for the @file{mule-base} package, version 1.37:
 
 @example
-   mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
-   cd $prefix/lib/xemacs/mule-packages RET
+   mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+   cd $prefix/share/xemacs/mule-packages RET
    gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
 
 Or if you have GNU tar, the last step can be:
@@ -351,11 +351,11 @@
 
 Install them by:
 
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
 
 Or, if you have GNU tar:
 
-@code{cd $prefix/lib/xemacs ; tar zxvf /path/to/<tarballname> RET}
+@code{cd $prefix/share/xemacs ; tar zxvf /path/to/<tarballname> RET}
 
 As the Sumo tarballs are not regenerated as often as the individual
 packages, it is recommended that you use the automatic package tools
--- a/src/ChangeLog	Wed Aug 24 11:06:41 2011 +0100
+++ b/src/ChangeLog	Wed Aug 24 11:07:26 2011 +0100
@@ -1,3 +1,41 @@
+2011-08-23  Stephen Turnbull  <stephen@xemacs.org>
+
+	Fix performance regression in refactored syntax cache setup.
+	More doc improvements.
+	
+	* syntax.h (enum syntax_source):
+	New.  Specify whether syntax is from property or buffer.
+	(struct syntax_cache):
+	Use enum syntax_source source, instead of no_syntax_table_prop
+	and use_code.
+	Improve comments.
+	(SOURCE_IS_TABLE):
+	New predicate.
+	(SYNTAX_CODE_FROM_CACHE):
+	Use it instead of use_code, and adjust logic.
+
+	* syntax.c (syntax_cache_table_was_changed):
+	Check cache->source (cache->no_syntax_table_prop is gone).
+	(reset_syntax_cache_range):
+	All information about OBJECT and BUFFER is in CACHE already.
+	Also reset markers in OBJECT if it is a buffer.
+	Rename INFINITE to VALID_EVERYWHERE.
+	(init_syntax_cache):
+	Initialize source (cache->no_syntax_table_prop is gone).
+	Maybe initialize start and end to null markers.
+	Initialize cache range with reset_syntax_cache_range.
+	(update_syntax_cache):
+	Use source instead of no_syntax_table_prop and use_code.
+	(setup_syntax_cache):
+	Add header comment.  Improve other comments.
+	Make calls to reset_syntax_cache_range and init_syntax_cache match
+	their prototypes.
+	(init_buffer_syntax_cache):
+	Use init_syntax_cache to do the work.
+	(signal_syntax_cache_extent_changed):
+	Make call to reset_syntax_cache_range match its prototype.
+	Improve local variable naming.
+
 2011-08-08  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* syntax.c (update_syntax_cache):
--- a/src/syntax.c	Wed Aug 24 11:06:41 2011 +0100
+++ b/src/syntax.c	Wed Aug 24 11:07:26 2011 +0100
@@ -273,7 +273,7 @@
 syntax_cache_table_was_changed (struct buffer *buf)
 {
   struct syntax_cache *cache = buf->syntax_cache;
-  if (cache->no_syntax_table_prop)
+  if (cache->source == syntax_source_buffer_table)
     {
       cache->syntax_table =
 	BUFFER_SYNTAX_TABLE (buf);
@@ -284,59 +284,96 @@
 
 static void
 reset_syntax_cache_range (struct syntax_cache *cache,  /* initialized cache */
-			  Lisp_Object object)	       /* string or buffer */
+			  int valid_everywhere)	/* non-zero if we can assume
+						   syntax-table properties
+						   never need be respected
+						   in the life of the cache */
 {
-  /* reinitialize cache parameters */
-  if (BUFFERP (object))
+  if (BUFFERP (cache->object))
     {
       /* make known region zero-length and reset insertion behavior */
-      Fset_marker (cache->start, make_int (1), object);
-      Fset_marker (cache->end, make_int (1), object);
+      Fset_marker (cache->start, make_int (1), cache->object);
+      Fset_marker (cache->end, make_int (1), cache->object);
       Fset_marker_insertion_type (cache->start, Qnil);
       Fset_marker_insertion_type (cache->end, Qt);
     }
-  else
+  /* #### Should reset "cache->source" here?
+     If so, also reset tables. */
+  if (valid_everywhere)
     {
-      /* invalidate the known region markers */
-      Fset_marker (cache->start, Qnil, Qnil);
-      Fset_marker (cache->end, Qnil, Qnil);
+      cache->prev_change = EMACS_INT_MIN;
+      cache->next_change = EMACS_INT_MAX;
     }
-  cache->no_syntax_table_prop = 1;
-  if (lookup_syntax_properties)
+  else /* valid nowhere */
     {
       cache->prev_change = -1;
       cache->next_change = -1;
     }
-  else
-    {
-      cache->prev_change = EMACS_INT_MIN;
-      cache->next_change = EMACS_INT_MAX;
-    }
 }
 
-/* init_syntax_cache
-   Arguments:
-   cache:  pointer to a zero-ed struct syntax_cache
-   object: a Lisp string or buffer
-   buffer: NULL or the struct buffer of buffer */
 static void
-init_syntax_cache (struct syntax_cache *cache,  /* cache must be zero'ed */
+init_syntax_cache (struct syntax_cache *cache,  /* xzero'ed memory */
 		   Lisp_Object object,		/* string or buffer */
-		   struct buffer *buffer)	/* may not be NULL */
+		   struct buffer *buffer)	/* buffer; if OBJECT is a
+						   buffer, this is the same */
 {
-  /* initialize cache resources */
   cache->object = object;
   cache->buffer = buffer;
+
+  cache->source = syntax_source_buffer_table;
   cache->syntax_table =
     BUFFER_SYNTAX_TABLE (cache->buffer);
   cache->mirror_table =
     BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
-  cache->start = Fmake_marker();
-  cache->end = Fmake_marker();
+
+  /* Qnil avoids GC'ing markers, which are useless for strings. */
+  cache->start = BUFFERP (object) ? Fmake_marker () : Qnil;
+  cache->end = BUFFERP (object) ? Fmake_marker () : Qnil;
+
+  reset_syntax_cache_range (cache, 0);
 }
 
 /* external syntax cache API */
 
+/* At this time (hg rev 5551:dab422055bab) setup_syntax_cache() is called
+   directly once in setup_buffer_syntax_cache and twice in regex.c.  The
+   calls in regex.c are obfuscated, so it's hard to tell, but it looks like
+   they can be called with OBJECT being a buffer.
+
+   "You are in a confusing maze of initializations, all alike."
+
+   reset_syntax_cache_range (3 uses in setup_syntax_cache,
+   signal_syntax_cache_extent_changed, and init_buffer_syntax_cache)
+   reinitializes:
+   1. if BUFFERP(OBJECT), marker positions to 1 (giving a null range)
+   2. if BUFFERP(OBJECT), marker movement type
+   3. cache range per VALID_EVERYWHERE
+
+   init_syntax_cache (2 uses in init_buffer_syntax_cache and
+   setup_syntax_cache) initializes:
+   1. source to syntax_source_buffer_table
+   2. syntax_table and mirror_syntax table to BUFFER's tables
+   3. marker members to BUFFERP(OBJECT) ? markers w/o position : Qnil
+   4. cache range with VALID_EVERYWHERE==0
+   5. object and buffer to corresponding arguments.
+
+   init_buffer_syntax_cache (1 use in buffer.c) initializes:
+   0. allocation of buffer's cache memory (done by allocator)
+   1. cache memory to zero (done by allocator)
+   2. cache to buffer's cache
+   3. cache members by init_syntax_cache with object==buffer==BUF.
+
+   setup_buffer_syntax_cache (1 call in font-lock.c, 1 use in search.c,
+   and 7 uses in this file) initializes:
+   0. buffer's syntax cache by calling setup_syntax_cache.
+
+   setup_buffer_syntax_cache and setup_syntax_cache are called by functions
+   that analyze text using character syntax.  They are called repeatedly on
+   the same cache.  init_syntax_cache and init_buffer_syntax_cache are
+   conceptually called once for each cache.  reset_syntax_cache_range may
+   be called repeatedly on the same cache.  The last three are for internal
+   use by the syntax setup code and buffer initialization. */
+
 struct syntax_cache *		/* return CACHE or the cache of OBJECT */
 setup_syntax_cache (struct syntax_cache *cache,	/* may be NULL only if
 						   OBJECT is a buffer */
@@ -344,22 +381,37 @@
 						   is associated with */
 		    struct buffer *buffer,	/* the buffer to use as source
 						   of the syntax table */
-		    Charxpos UNUSED (from),	/* initial position of cache */
-		    int UNUSED (count))		/* direction? see code */
+		    Charxpos from,		/* initial position of cache */
+		    int count)			/* direction? see code */
 {
-  /* If OBJECT is a buffer, use its cache, otherwise use CACHE.
-     Initialize CACHE.  Invalidate the cache if the syntax-table property is
-     being respected, otherwise make it valid for the whole object. */
+  /* If OBJECT is a buffer, use its cache; else use CACHE and initialize it.
+     Invalidate the cache if the syntax-table property is being respected;
+     else make it valid for the whole object. */
   if (BUFFERP (object))
     {
       cache = XBUFFER (object)->syntax_cache;
+      if (!lookup_syntax_properties)
+	reset_syntax_cache_range (cache, 1);
     }
   else
     {
       xzero (*cache);
       init_syntax_cache (cache, object, buffer);
     }
-  reset_syntax_cache_range (cache, object);
+
+   if (lookup_syntax_properties)
+     {
+       if (count <= 0)
+	 {
+	   --from;
+	   from = buffer_or_string_clip_to_accessible_char (cache->object,
+							    from);
+	 }
+       /* If lookup_syntax_properties && BUFFERP (object), this
+	  optimization may matter. */
+       if (!(from >= cache->prev_change && from < cache->next_change))
+	 update_syntax_cache (cache, from, count);
+     }
 
 #ifdef NOT_WORTH_THE_EFFORT
   update_mirror_syntax_if_dirty (cache->mirror_table);
@@ -454,24 +506,21 @@
   
   if (!NILP (Fsyntax_table_p (tmp_table)))
     {
-      cache->use_code = 0;
+      cache->source = syntax_source_property_table;
       cache->syntax_table = tmp_table;
       cache->mirror_table = XCHAR_TABLE (tmp_table)->mirror_table;
-      cache->no_syntax_table_prop = 0;
 #ifdef NOT_WORTH_THE_EFFORT
       update_mirror_syntax_if_dirty (cache->mirror_table);
 #endif /* NOT_WORTH_THE_EFFORT */
     } 
   else if (CONSP (tmp_table) && INTP (XCAR (tmp_table)))
     {
-      cache->use_code = 1;
+      cache->source = syntax_source_property_code;
       cache->syntax_code = XINT (XCAR (tmp_table));
-      cache->no_syntax_table_prop = 0;
     }
   else 
     {
-      cache->use_code = 0;
-      cache->no_syntax_table_prop = 1;
+      cache->source = syntax_source_buffer_table;
       cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer);
       cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
 #ifdef NOT_WORTH_THE_EFFORT
@@ -501,14 +550,15 @@
 void
 init_buffer_syntax_cache (struct buffer *buf)
 {
+  struct syntax_cache *cache;
 #ifdef NEW_GC
-  buf->syntax_cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
+  cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
 #else /* not NEW_GC */
-  buf->syntax_cache = xnew_and_zero (struct syntax_cache);
+  cache = xnew_and_zero (struct syntax_cache);
 #endif /* not NEW_GC */
 
-  init_syntax_cache (buf->syntax_cache, wrap_buffer(buf), buf);
-  reset_syntax_cache_range (buf->syntax_cache, wrap_buffer(buf));
+  init_syntax_cache (cache, wrap_buffer (buf), buf);
+  buf->syntax_cache = cache;
 }
 
 /* finalize the syntax cache for BUF */
@@ -535,18 +585,18 @@
 void
 signal_syntax_cache_extent_changed (EXTENT extent)
 {
-  Lisp_Object buffer = Fextent_object (wrap_extent (extent));
-  if (BUFFERP (buffer))
+  Lisp_Object object = Fextent_object (wrap_extent (extent));
+  if (BUFFERP (object))
     {
-      struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache;
-      Bytexpos start = extent_endpoint_byte (extent, 0);
-      Bytexpos end = extent_endpoint_byte (extent, 1);
-      Bytexpos start2 = byte_marker_position (cache->start);
-      Bytexpos end2 = byte_marker_position (cache->end);
+      struct syntax_cache *cache = XBUFFER (object)->syntax_cache;
+      Bytexpos extent_start = extent_endpoint_byte (extent, 0);
+      Bytexpos extent_end = extent_endpoint_byte (extent, 1);
+      Bytexpos cache_start = byte_marker_position (cache->start);
+      Bytexpos cache_end = byte_marker_position (cache->end);
       /* If the extent is entirely before or entirely after the cache
 	 range, it doesn't overlap.  Otherwise, invalidate the range. */
-      if (!(end < start2 || start > end2))
-	reset_syntax_cache_range (cache, buffer);
+      if (!(extent_end < cache_start || extent_start > cache_end))
+	reset_syntax_cache_range (cache, 0);
     }
 }
 
--- a/src/syntax.h	Wed Aug 24 11:06:41 2011 +0100
+++ b/src/syntax.h	Wed Aug 24 11:07:26 2011 +0100
@@ -234,20 +234,21 @@
    #### sjt sez: I'm not sure I believe that last claim.  That seems to
    require that we use directional information, etc, but that is ignored in
    the current implementation. */
+
+enum syntax_source { syntax_source_property_code = 0,
+		     syntax_source_property_table = 1,
+		     syntax_source_buffer_table = 2 };
+#define SOURCE_IS_TABLE(source) (source)
+
 struct syntax_cache
 {
 #ifdef NEW_GC
   NORMAL_LISP_OBJECT_HEADER header;
 #endif /* NEW_GC */
-  int use_code;			/* Non-zero if a syntax-table property
-				   specified a syntax code.  When zero, the
-				   syntax_code member is invalid.  Otherwise
-				   the syntax_table member is invalid. */
-  int no_syntax_table_prop;	/* If non-zero, there was no `syntax-table'
-				   property on the current range, and so we're
-				   using the buffer's syntax table.
-				   Then we must invalidate the cache if the
-				   buffer's syntax table is changed. */
+  enum syntax_source source;	/* Source of syntax information: the buffer's
+				   syntax table, a syntax table specified by
+				   a syntax-table property, or a syntax code
+				   specified by a syntax-table property. */
   Lisp_Object object;		/* The buffer or string the current syntax
 				   cache applies to, or Qnil for a string of
 				   text not coming from a buffer or string. */
@@ -260,6 +261,7 @@
   Lisp_Object mirror_table;	/* Mirror table for this table. */
   Lisp_Object start, end;	/* Markers to keep track of the known region
 				   in a buffer.
+				   Both are Qnil if object is a string.
 				   Normally these correspond to prev_change
 				   and next_change, respectively, except when
 				   insertions and deletions occur.  Then
@@ -269,7 +271,8 @@
 				   We'd like to use an extent, but it seems
 				   that having an extent over the entire
 				   buffer causes serious slowdowns in extent
-				   operations!  Yuck! */
+				   operations!  Yuck!
+				   #### May not be true any more. */
   Charxpos next_change;		/* Position of the next extent change. */
   Charxpos prev_change;		/* Position of the previous extent change. */
 };
@@ -341,9 +344,10 @@
 #define SYNTAX_FROM_CACHE(cache, c)			\
    SYNTAX_FROM_CODE (SYNTAX_CODE_FROM_CACHE (cache, c))
 
-#define SYNTAX_CODE_FROM_CACHE(cache, c)				\
-  ((cache)->use_code ? (cache)->syntax_code				\
-   : SYNTAX_CODE ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c)	\
+  (SOURCE_IS_TABLE ((cache)->source)		\
+   ? SYNTAX_CODE ((cache)->mirror_table, c)	\
+   : (cache)->syntax_code)
 
 #ifdef NOT_WORTH_THE_EFFORT
 /* If we really cared about the theoretical performance hit of the dirty
@@ -356,9 +360,10 @@
    functions and could execute arbitrary Lisp very easily), etc.  The QUIT
    problem is the biggest one, probably, and one of the main reasons it's
    probably just not worth it. */
-#define SYNTAX_CODE_FROM_CACHE(cache, c)				\
-  ((cache)->use_code ? (cache)->syntax_code				\
-   : SYNTAX_CODE_1 ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c)	\
+  (SOURCE_IS_TABLE ((cache)->source)		\
+   ? SYNTAX_CODE_1 ((cache)->mirror_table, c)	\
+   : (cache)->syntax_code)
 #endif